Clang tautological-compare fails to warn in cases where gcc doesn't

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Clang tautological-compare fails to warn in cases where gcc doesn't

Louis Dionne via cfe-dev

Here is a simple test where clang fails to issue a warning in the first function but warns in the second function. gcc (6.x and above) gives a warning in both cases. Is the pointer dereference throwing clang off? Why should the pointer dereference matter in this case?

 

struct Foo {

    int a;

};

 

// Case 1

int cmp(const Foo* x, const Foo* y);

int cmp(const Foo* x, const Foo* y)

{

    if (x->a < x->a) {

        return -1;

    } else if (y->a > y->a) {

        return 1;

    }

    return 0;

}

 

// Case 2

int cmp2(int x, int y);

int cmp2(int x, int y)

{

    if (x < x) {

        return -1;

    } else if (y > y) {

        return 1;

    }

    return 0;

}

 

// gcc 6.2 with -Wall

x.cc: In function ?int cmp(const Foo*, const Foo*)?:

x.cc:7:14: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x->a < x->a) {

         ~~~~~^~~~~~

x.cc:9:21: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y->a > y->a) {

                ~~~~~^~~~~~

x.cc: In function ?int cmp2(int, int)?:

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x < x) {

         ~~^~~

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y > y) {

                ~~^~~

 

// clang 6.0.1 -Wall

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

    if (x < x) {

          ^

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

    } else if (y > y) {

                 ^

2 warnings generated.

 

 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang tautological-compare fails to warn in cases where gcc doesn't

Louis Dionne via cfe-dev
I suspect that clang cannot satisfy itself that the x->a cannot be changed by somebody else between the evaluation of the lhs and the rhs of the comparison.
All it knows is that the function cmp cannot modify it.
I'd say clang is correct, but I haven't studied the problem much.

Maurizio

On Thu, Apr 12, 2018 at 10:39 AM, Riyaz Puthiyapurayil via cfe-dev <[hidden email]> wrote:

Here is a simple test where clang fails to issue a warning in the first function but warns in the second function. gcc (6.x and above) gives a warning in both cases. Is the pointer dereference throwing clang off? Why should the pointer dereference matter in this case?

 

struct Foo {

    int a;

};

 

// Case 1

int cmp(const Foo* x, const Foo* y);

int cmp(const Foo* x, const Foo* y)

{

    if (x->a < x->a) {

        return -1;

    } else if (y->a > y->a) {

        return 1;

    }

    return 0;

}

 

// Case 2

int cmp2(int x, int y);

int cmp2(int x, int y)

{

    if (x < x) {

        return -1;

    } else if (y > y) {

        return 1;

    }

    return 0;

}

 

// gcc 6.2 with -Wall

x.cc: In function ?int cmp(const Foo*, const Foo*)?:

x.cc:7:14: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x->a < x->a) {

         ~~~~~^~~~~~

x.cc:9:21: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y->a > y->a) {

                ~~~~~^~~~~~

x.cc: In function ?int cmp2(int, int)?:

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x < x) {

         ~~^~~

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y > y) {

                ~~^~~

 

// clang 6.0.1 -Wall

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

    if (x < x) {

          ^

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

    } else if (y > y) {

                 ^

2 warnings generated.

 

 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang tautological-compare fails to warn in cases where gcc doesn't

Louis Dionne via cfe-dev
It's not volatile, so it seems inappropriate for clang to think that it could be modified in between. In fact, at -O1, the comparisons are optimized out anyway, so it's clear that the warning should be in place to tell developers that this comparison is not going to be performed:

cmp(Foo const*, Foo const*): # @cmp(Foo const*, Foo const*)
xor eax, eax
ret

(clang 6.0.0)

On Thu, Apr 12, 2018 at 8:35 AM, Maurizio Vitale via cfe-dev <[hidden email]> wrote:
I suspect that clang cannot satisfy itself that the x->a cannot be changed by somebody else between the evaluation of the lhs and the rhs of the comparison.
All it knows is that the function cmp cannot modify it.
I'd say clang is correct, but I haven't studied the problem much.

Maurizio

On Thu, Apr 12, 2018 at 10:39 AM, Riyaz Puthiyapurayil via cfe-dev <[hidden email]> wrote:

Here is a simple test where clang fails to issue a warning in the first function but warns in the second function. gcc (6.x and above) gives a warning in both cases. Is the pointer dereference throwing clang off? Why should the pointer dereference matter in this case?

 

struct Foo {

    int a;

};

 

// Case 1

int cmp(const Foo* x, const Foo* y);

int cmp(const Foo* x, const Foo* y)

{

    if (x->a < x->a) {

        return -1;

    } else if (y->a > y->a) {

        return 1;

    }

    return 0;

}

 

// Case 2

int cmp2(int x, int y);

int cmp2(int x, int y)

{

    if (x < x) {

        return -1;

    } else if (y > y) {

        return 1;

    }

    return 0;

}

 

// gcc 6.2 with -Wall

x.cc: In function ?int cmp(const Foo*, const Foo*)?:

x.cc:7:14: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x->a < x->a) {

         ~~~~~^~~~~~

x.cc:9:21: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y->a > y->a) {

                ~~~~~^~~~~~

x.cc: In function ?int cmp2(int, int)?:

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x < x) {

         ~~^~~

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y > y) {

                ~~^~~

 

// clang 6.0.1 -Wall

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

    if (x < x) {

          ^

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

    } else if (y > y) {

                 ^

2 warnings generated.

 

 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang tautological-compare fails to warn in cases where gcc doesn't

Louis Dionne via cfe-dev

I agree. Clang should warn in this case. If 'const' is changed to 'volatile', then gcc doesn't warn either (as expected).

 

I will file a bug.

 

/Riyaz

 

From: Matthew Del Buono [mailto:[hidden email]]
Sent: Thursday, April 12, 2018 9:29 AM
To: Maurizio Vitale <[hidden email]>
Cc: Riyaz Puthiyapurayil <[hidden email]>; [hidden email]
Subject: Re: [cfe-dev] Clang tautological-compare fails to warn in cases where gcc doesn't

 

It's not volatile, so it seems inappropriate for clang to think that it could be modified in between. In fact, at -O1, the comparisons are optimized out anyway, so it's clear that the warning should be in place to tell developers that this comparison is not going to be performed:

 

cmp(Foo const*, Foo const*): # @cmp(Foo const*, Foo const*)

xor eax, eax

ret

 

(clang 6.0.0)

 

On Thu, Apr 12, 2018 at 8:35 AM, Maurizio Vitale via cfe-dev <[hidden email]> wrote:

I suspect that clang cannot satisfy itself that the x->a cannot be changed by somebody else between the evaluation of the lhs and the rhs of the comparison.

All it knows is that the function cmp cannot modify it.
I'd say clang is correct, but I haven't studied the problem much.

 

Maurizio

 

On Thu, Apr 12, 2018 at 10:39 AM, Riyaz Puthiyapurayil via cfe-dev <[hidden email]> wrote:

Here is a simple test where clang fails to issue a warning in the first function but warns in the second function. gcc (6.x and above) gives a warning in both cases. Is the pointer dereference throwing clang off? Why should the pointer dereference matter in this case?

 

struct Foo {

    int a;

};

 

// Case 1

int cmp(const Foo* x, const Foo* y);

int cmp(const Foo* x, const Foo* y)

{

    if (x->a < x->a) {

        return -1;

    } else if (y->a > y->a) {

        return 1;

    }

    return 0;

}

 

// Case 2

int cmp2(int x, int y);

int cmp2(int x, int y)

{

    if (x < x) {

        return -1;

    } else if (y > y) {

        return 1;

    }

    return 0;

}

 

// gcc 6.2 with -Wall

x.cc: In function ?int cmp(const Foo*, const Foo*)?:

x.cc:7:14: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x->a < x->a) {

         ~~~~~^~~~~~

x.cc:9:21: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y->a > y->a) {

                ~~~~~^~~~~~

x.cc: In function ?int cmp2(int, int)?:

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x < x) {

         ~~^~~

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y > y) {

                ~~^~~

 

// clang 6.0.1 -Wall

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

    if (x < x) {

          ^

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

    } else if (y > y) {

                 ^

2 warnings generated.

 

 

 

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang tautological-compare fails to warn in cases where gcc doesn't

Louis Dionne via cfe-dev

https://bugs.llvm.org/show_bug.cgi?id=37113

 

From: Riyaz Puthiyapurayil [mailto:[hidden email]]
Sent: Thursday, April 12, 2018 12:21 PM
To: Matthew Del Buono <[hidden email]>; Maurizio Vitale <[hidden email]>
Cc: Riyaz Puthiyapurayil <[hidden email]>; [hidden email]
Subject: RE: [cfe-dev] Clang tautological-compare fails to warn in cases where gcc doesn't

 

I agree. Clang should warn in this case. If 'const' is changed to 'volatile', then gcc doesn't warn either (as expected).

 

I will file a bug.

 

/Riyaz

 

From: Matthew Del Buono [[hidden email]]
Sent: Thursday, April 12, 2018 9:29 AM
To: Maurizio Vitale <[hidden email]>
Cc: Riyaz Puthiyapurayil <[hidden email]>; [hidden email]
Subject: Re: [cfe-dev] Clang tautological-compare fails to warn in cases where gcc doesn't

 

It's not volatile, so it seems inappropriate for clang to think that it could be modified in between. In fact, at -O1, the comparisons are optimized out anyway, so it's clear that the warning should be in place to tell developers that this comparison is not going to be performed:

 

cmp(Foo const*, Foo const*): # @cmp(Foo const*, Foo const*)

xor eax, eax

ret

 

(clang 6.0.0)

 

On Thu, Apr 12, 2018 at 8:35 AM, Maurizio Vitale via cfe-dev <[hidden email]> wrote:

I suspect that clang cannot satisfy itself that the x->a cannot be changed by somebody else between the evaluation of the lhs and the rhs of the comparison.

All it knows is that the function cmp cannot modify it.
I'd say clang is correct, but I haven't studied the problem much.

 

Maurizio

 

On Thu, Apr 12, 2018 at 10:39 AM, Riyaz Puthiyapurayil via cfe-dev <[hidden email]> wrote:

Here is a simple test where clang fails to issue a warning in the first function but warns in the second function. gcc (6.x and above) gives a warning in both cases. Is the pointer dereference throwing clang off? Why should the pointer dereference matter in this case?

 

struct Foo {

    int a;

};

 

// Case 1

int cmp(const Foo* x, const Foo* y);

int cmp(const Foo* x, const Foo* y)

{

    if (x->a < x->a) {

        return -1;

    } else if (y->a > y->a) {

        return 1;

    }

    return 0;

}

 

// Case 2

int cmp2(int x, int y);

int cmp2(int x, int y)

{

    if (x < x) {

        return -1;

    } else if (y > y) {

        return 1;

    }

    return 0;

}

 

// gcc 6.2 with -Wall

x.cc: In function ?int cmp(const Foo*, const Foo*)?:

x.cc:7:14: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x->a < x->a) {

         ~~~~~^~~~~~

x.cc:9:21: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y->a > y->a) {

                ~~~~~^~~~~~

x.cc: In function ?int cmp2(int, int)?:

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

     if (x < x) {

         ~~^~~

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

     } else if (y > y) {

                ~~^~~

 

// clang 6.0.1 -Wall

x.cc:17:11: warning: self-comparison always evaluates to false [-Wtautological-compare]

    if (x < x) {

          ^

x.cc:19:18: warning: self-comparison always evaluates to false [-Wtautological-compare]

    } else if (y > y) {

                 ^

2 warnings generated.

 

 

 

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev