]> granicus.if.org Git - clang/commitdiff
Remove bogus check for template specialization from self-comparison warning.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sun, 7 Jan 2018 22:25:55 +0000 (22:25 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sun, 7 Jan 2018 22:25:55 +0000 (22:25 +0000)
The important check is that we're not within a template *instantiation*, which
we check separately.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321977 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaCXX/self-comparison.cpp

index e9e65fc1fc5a146ee55a2ad15bc13eb8ad8be17b..39b532309d76b034969ee01eccd01129037e0196 100644 (file)
@@ -9300,16 +9300,6 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
   return LHSType;
 }
 
-static bool IsWithinTemplateSpecialization(Decl *D) {
-  if (DeclContext *DC = D->getDeclContext()) {
-    if (isa<ClassTemplateSpecializationDecl>(DC))
-      return true;
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DC))
-      return FD->isFunctionTemplateSpecialization();
-  }
-  return false;
-}
-
 /// If two different enums are compared, raise a warning.
 static void checkEnumComparison(Sema &S, SourceLocation Loc, Expr *LHS,
                                 Expr *RHS) {
@@ -9621,14 +9611,13 @@ static void diagnoseTautologicalComparison(Sema &S, SourceLocation Loc,
   //
   // NOTE: Don't warn about comparison expressions resulting from macro
   // expansion. Also don't warn about comparisons which are only self
-  // comparisons within a template specialization. The warnings should catch
+  // comparisons within a template instantiation. The warnings should catch
   // obvious cases in the definition of the template anyways. The idea is to
   // warn when the typed comparison operator will always evaluate to the same
   // result.
   ValueDecl *DL = getCompareDecl(LHSStripped);
   ValueDecl *DR = getCompareDecl(RHSStripped);
-  if (DL && DR && declaresSameEntity(DL, DR) &&
-      !IsWithinTemplateSpecialization(DL)) {
+  if (DL && DR && declaresSameEntity(DL, DR)) {
     StringRef Result;
     switch (Opc) {
     case BO_EQ: case BO_LE: case BO_GE:
index 2af19abb30a53adc611d752e9a69bc20fde89e42..ac129b68a67a9219514222a9d30ae64791e98606 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++2a
 
 int foo(int x) {
   return x == x; // expected-warning {{self-comparison always evaluates to true}}
@@ -25,3 +25,18 @@ struct A {
 namespace NA { extern "C" int x[3]; }
 namespace NB { extern "C" int x[3]; }
 bool k = NA::x == NB::x; // expected-warning {{self-comparison always evaluates to true}}
+
+template<typename T> struct Y { static inline int n; };
+bool f() {
+  return
+    Y<int>::n == Y<int>::n || // expected-warning {{self-comparison always evaluates to true}}
+    Y<void>::n == Y<int>::n;
+}
+template<typename T, typename U>
+bool g() {
+  // FIXME: Ideally we'd produce a self-comparison warning on the first of these.
+  return
+    Y<T>::n == Y<T>::n ||
+    Y<T>::n == Y<U>::n;
+}
+template bool g<int, int>(); // should not produce any warnings