diff --git a/internal/impl/message_field.go b/internal/impl/message_field.go index ec29a9b2..436cd288 100644 --- a/internal/impl/message_field.go +++ b/internal/impl/message_field.go @@ -6,6 +6,7 @@ package impl import ( "fmt" + "math" "reflect" "github.com/golang/protobuf/v2/internal/flags" @@ -197,7 +198,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField) fieldIn case reflect.Uint32, reflect.Uint64: return rv.Uint() != 0 case reflect.Float32, reflect.Float64: - return rv.Float() != 0 + return rv.Float() != 0 || math.Signbit(rv.Float()) case reflect.String, reflect.Slice: return rv.Len() > 0 default: diff --git a/internal/impl/message_test.go b/internal/impl/message_test.go index ef71ca1e..b5a9af25 100644 --- a/internal/impl/message_test.go +++ b/internal/impl/message_test.go @@ -387,6 +387,11 @@ func TestScalarProto3(t *testing.T) { }, clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, equalMessage{&ScalarProto3{}}, + + // Verify that -0 triggers proper Has behavior. + hasFields{6: false, 7: false}, + setFields{6: V(float32(math.Copysign(0, -1))), 7: V(float64(math.Copysign(0, -1)))}, + hasFields{6: true, 7: true}, }) // Test read-only operations on nil message.