https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66500
Bug ID: 66500 Summary: C/C++ inconsistency in diagnostic context involving macros Product: gcc Version: 5.1.0 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- The following test case shows that gcc and g++ emit different and sometimes misleading context in diagnostic messages involving macros: 1) In C mode, gcc points at the offending operator, while in C++ mode it points at an operand. Since in this case the type of the operand the C++ diagnostic points to is (before conversion) int, the diagnostic is misleading. 2) In C mode, gcc includes a note showing the context from which the macro was invoked when the operand is the result of macro expansion, while in C++ mode it does the same for the operand. For consistency's sake it would be useful to harmonize the two. It seems to me that the C output makes more sense than the output produced in C++ mode since the issue the warning points out is not specific to one or the other operand but rather to the operator for operators of the (converted) type. $ (set -x && cat u.c && gcc -S -Wfloat-equal -o/dev/null u.c && gcc -S -Wfloat-equal -o/dev/null -xc++ u.c) + cat u.c int f0 (double x, int y) { return x == y; } #define A(A) A int f1 (double x, int y) { return A (x) == A (y); } #define EQL == int f2 (double x, int y) { return x EQL y; } #define EQUAL(A, B) A == B int f3 (double x, int y) { return EQUAL (x, y); } + gcc -S -Wfloat-equal -o/dev/null u.c u.c: In function ‘f0’: u.c:2:14: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return x == y; ^ u.c: In function ‘f1’: u.c:7:18: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return A (x) == A (y); ^ u.c: In function ‘f2’: u.c:10:13: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] #define EQL == ^ u.c:12:14: note: in expansion of macro ‘EQL’ return x EQL y; ^ u.c: In function ‘f3’: u.c:15:23: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] #define EQUAL(A, B) A == B ^ u.c:17:12: note: in expansion of macro ‘EQUAL’ return EQUAL (x, y); ^ + gcc -S -Wfloat-equal -o/dev/null -xc++ u.c u.c: In function ‘int f0(double, int)’: u.c:2:17: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return x == y; ^ u.c: In function ‘int f1(double, int)’: u.c:7:24: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return A (x) == A (y); ^ u.c:5:14: note: in definition of macro ‘A’ #define A(A) A ^ u.c: In function ‘int f2(double, int)’: u.c:12:18: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return x EQL y; ^ u.c: In function ‘int f3(double, int)’: u.c:17:22: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return EQUAL (x, y); ^ u.c:15:26: note: in definition of macro ‘EQUAL’ #define EQUAL(A, B) A == B ^ In contrast, Clang output is consistent and clear in both modes without notes that include the context of macro expansion where it isn't necessary: + /build/llvm-3.6.0/bin/clang -S -Wfloat-equal -o/dev/null u.c u.c:2:14: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return x == y; ~ ^ ~ u.c:7:18: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return A (x) == A (y); ~ ^ ~ u.c:12:14: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return x EQL y; ~ ^ ~ u.c:10:13: note: expanded from macro 'EQL' #define EQL == ^ u.c:17:12: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return EQUAL (x, y); ^ ~ ~ u.c:15:23: note: expanded from macro 'EQUAL' #define EQUAL(A, B) A == B ^ 4 warnings generated. + /build/llvm-3.6.0/bin/clang++ -S -Wfloat-equal -o/dev/null -xc++ u.c u.c:2:14: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return x == y; ~ ^ ~ u.c:7:18: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return A (x) == A (y); ~ ^ ~ u.c:12:14: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return x EQL y; ~ ^ ~ u.c:10:13: note: expanded from macro 'EQL' #define EQL == ^ u.c:17:12: warning: comparing floating point with == or != is unsafe [-Wfloat-equal] return EQUAL (x, y); ^ ~ ~ u.c:15:23: note: expanded from macro 'EQUAL' #define EQUAL(A, B) A == B ^ 4 warnings generated.