Bug 66500 - C/C++ inconsistency in diagnostic context involving macros
Summary: C/C++ inconsistency in diagnostic context involving macros
Status: RESOLVED DUPLICATE of bug 52998
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 5.1.0
: P3 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2015-06-11 02:42 UTC by Martin Sebor
Modified: 2015-06-11 15:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2015-06-11 02:42:07 UTC
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.
Comment 1 Manuel López-Ibáñez 2015-06-11 05:17:38 UTC
Dup of PR52998 ?

You can find more bugs about the macro unwinder at https://gcc.gnu.org/wiki/Better_Diagnostics (I).
Comment 2 Martin Sebor 2015-06-11 15:12:28 UTC
Yes, it is a duplicate of pr52998.  Thanks for the pointers!

*** This bug has been marked as a duplicate of bug 52998 ***