[llvm-branch-commits] [cfe-branch] r214693 - Merging r213840:

Bill Wendling isanbard at gmail.com
Sun Aug 3 21:35:31 PDT 2014


Author: void
Date: Sun Aug  3 23:35:31 2014
New Revision: 214693

URL: http://llvm.org/viewvc/llvm-project?rev=214693&view=rev
Log:
Merging r213840:
------------------------------------------------------------------------
r213840 | rtrieu | 2014-07-23 21:24:50 -0700 (Wed, 23 Jul 2014) | 2 lines

Add support for nullptr template arguments to template type diffing.

------------------------------------------------------------------------

Modified:
    cfe/branches/release_35/   (props changed)
    cfe/branches/release_35/lib/AST/ASTDiagnostic.cpp
    cfe/branches/release_35/test/Misc/diag-template-diffing.cpp

Propchange: cfe/branches/release_35/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sun Aug  3 23:35:31 2014
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:213609,213611,213613,213741,213993,213998,214208
+/cfe/trunk:213609,213611,213613,213741,213840,213993,213998,214208
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_35/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_35/lib/AST/ASTDiagnostic.cpp?rev=214693&r1=214692&r2=214693&view=diff
==============================================================================
--- cfe/branches/release_35/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/branches/release_35/lib/AST/ASTDiagnostic.cpp Sun Aug  3 23:35:31 2014
@@ -472,6 +472,9 @@ class TemplateDiff {
       /// FromExpr, ToExpr - The expression arguments.
       Expr *FromExpr, *ToExpr;
 
+      /// FromNullPtr, ToNullPtr - If the template argument is a nullptr
+      bool FromNullPtr, ToNullPtr;
+
       /// FromTD, ToTD - The template decl for template template
       /// arguments or the type arguments that are templates.
       TemplateDecl *FromTD, *ToTD;
@@ -501,6 +504,7 @@ class TemplateDiff {
       DiffNode(unsigned ParentNode = 0)
         : Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),
           FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr),
+          FromNullPtr(false), ToNullPtr(false),
           FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false),
           IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr),
           FromAddressOf(false), ToAddressOf(false), FromDefault(false),
@@ -574,6 +578,12 @@ class TemplateDiff {
       FlatTree[CurrentNode].Same = Same;
     }
 
+    /// SetNullPtr - Sets the NullPtr flags of the current node.
+    void SetNullPtr(bool FromNullPtr, bool ToNullPtr) {
+      FlatTree[CurrentNode].FromNullPtr = FromNullPtr;
+      FlatTree[CurrentNode].ToNullPtr = ToNullPtr;
+    }
+
     /// SetDefault - Sets FromDefault and ToDefault flags of the current node.
     void SetDefault(bool FromDefault, bool ToDefault) {
       FlatTree[CurrentNode].FromDefault = FromDefault;
@@ -696,6 +706,16 @@ class TemplateDiff {
       return FlatTree[ReadNode].NextNode != 0;
     }
 
+    /// FromNullPtr - Returns true if the from argument is null.
+    bool FromNullPtr() {
+      return FlatTree[ReadNode].FromNullPtr;
+    }
+
+    /// ToNullPtr - Returns true if the to argument is null.
+    bool ToNullPtr() {
+      return FlatTree[ReadNode].ToNullPtr;
+    }
+
     /// FromDefault - Return true if the from argument is the default.
     bool FromDefault() {
       return FlatTree[ReadNode].FromDefault;
@@ -934,6 +954,10 @@ class TemplateDiff {
         bool HasToValueDecl =
             !ToIter.isEnd() &&
             ToIter->getKind() == TemplateArgument::Declaration;
+        bool FromNullPtr = !FromIter.isEnd() &&
+                           FromIter->getKind() == TemplateArgument::NullPtr;
+        bool ToNullPtr =
+            !ToIter.isEnd() && ToIter->getKind() == TemplateArgument::NullPtr;
 
         assert(((!HasFromInt && !HasToInt) ||
                 (!HasFromValueDecl && !HasToValueDecl)) &&
@@ -943,16 +967,25 @@ class TemplateDiff {
           FromInt = FromIter->getAsIntegral();
         else if (HasFromValueDecl)
           FromValueDecl = FromIter->getAsDecl();
-        else
+        else if (!FromNullPtr)
           FromExpr = GetExpr(FromIter, DefaultNTTPD);
 
         if (HasToInt)
           ToInt = ToIter->getAsIntegral();
         else if (HasToValueDecl)
           ToValueDecl = ToIter->getAsDecl();
-        else
+        else if (!ToNullPtr)
           ToExpr = GetExpr(ToIter, DefaultNTTPD);
 
+        bool TemplateArgumentIsPointerType =
+            DefaultNTTPD->getType()->isPointerType();
+        if (FromExpr && TemplateArgumentIsPointerType) {
+          FromNullPtr = CheckForNullPtr(FromExpr);
+        }
+        if (ToExpr && TemplateArgumentIsPointerType) {
+          ToNullPtr = CheckForNullPtr(ToExpr);
+        }
+
         if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
           Tree.SetNode(FromExpr, ToExpr);
           Tree.SetDefault(FromIter.isEnd() && FromExpr,
@@ -972,7 +1005,9 @@ class TemplateDiff {
             Tree.SetSame(false);
             Tree.SetKind(DiffTree::Integer);
           } else {
-            Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr));
+            Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr) ||
+                         (FromNullPtr && ToNullPtr));
+            Tree.SetNullPtr(FromNullPtr, ToNullPtr);
             Tree.SetKind(DiffTree::Expression);
           }
         } else if (HasFromInt || HasToInt) {
@@ -1020,6 +1055,7 @@ class TemplateDiff {
               }
             }
           }
+          Tree.SetNullPtr(FromNullPtr, ToNullPtr);
           Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
           Tree.SetSame(FromValueDecl && ToValueDecl &&
                        FromValueDecl->getCanonicalDecl() ==
@@ -1187,13 +1223,36 @@ class TemplateDiff {
       }
     DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
     if (!DRE) {
-      DRE = cast<DeclRefExpr>(
-          cast<UnaryOperator>(ArgExpr->IgnoreParens())->getSubExpr());
+      UnaryOperator *UO = dyn_cast<UnaryOperator>(ArgExpr->IgnoreParens());
+      if (!UO)
+        return nullptr;
+      DRE = cast<DeclRefExpr>(UO->getSubExpr());
     }
 
     return DRE->getDecl();
   }
 
+  /// CheckForNullPtr - returns true if the expression can be evaluated as
+  /// a null pointer
+  bool CheckForNullPtr(Expr *E) {
+    assert(E && "Expected expression");
+
+    E = E->IgnoreParenCasts();
+    if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
+      return true;
+
+    DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
+    if (!DRE)
+      return false;
+
+    VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
+    if (!VD || !VD->hasInit())
+      return false;
+
+    return VD->getInit()->IgnoreParenCasts()->isNullPointerConstant(
+        Context, Expr::NPC_ValueDependentIsNull);
+  }
+
   /// GetTemplateDecl - Retrieves the template template arguments, including
   /// default arguments.
   TemplateDecl *GetTemplateDecl(const TSTiterator &Iter,
@@ -1300,8 +1359,8 @@ class TemplateDiff {
       case DiffTree::Expression: {
         Expr *FromExpr, *ToExpr;
         Tree.GetNode(FromExpr, ToExpr);
-        PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
-                  Tree.NodeIsSame());
+        PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(),
+                  Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
         return;
       }
       case DiffTree::TemplateTemplate: {
@@ -1327,7 +1386,8 @@ class TemplateDiff {
         bool FromAddressOf, ToAddressOf;
         Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
         PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
-                       Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
+                       Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(),
+                       Tree.ToDefault(), Tree.NodeIsSame());
         return;
       }
       case DiffTree::Template: {
@@ -1452,36 +1512,41 @@ class TemplateDiff {
 
   /// PrintExpr - Prints out the expr template arguments, highlighting argument
   /// differences.
-  void PrintExpr(const Expr *FromExpr, const Expr *ToExpr,
-                 bool FromDefault, bool ToDefault, bool Same) {
+  void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromNullPtr,
+                 bool ToNullPtr, bool FromDefault, bool ToDefault, bool Same) {
     assert((FromExpr || ToExpr) &&
             "Only one template argument may be missing.");
     if (Same) {
-      PrintExpr(FromExpr);
+      PrintExpr(FromExpr, FromNullPtr);
     } else if (!PrintTree) {
       OS << (FromDefault ? "(default) " : "");
       Bold();
-      PrintExpr(FromExpr);
+      PrintExpr(FromExpr, FromNullPtr);
       Unbold();
     } else {
       OS << (FromDefault ? "[(default) " : "[");
       Bold();
-      PrintExpr(FromExpr);
+      PrintExpr(FromExpr, FromNullPtr);
       Unbold();
       OS << " != " << (ToDefault ? "(default) " : "");
       Bold();
-      PrintExpr(ToExpr);
+      PrintExpr(ToExpr, ToNullPtr);
       Unbold();
       OS << ']';
     }
   }
 
   /// PrintExpr - Actual formatting and printing of expressions.
-  void PrintExpr(const Expr *E) {
-    if (!E)
-      OS << "(no argument)";
-    else
+  void PrintExpr(const Expr *E, bool NullPtr = false) {
+    if (E) {
       E->printPretty(OS, nullptr, Policy);
+      return;
+    }
+    if (NullPtr) {
+      OS << "nullptr";
+      return;
+    }
+    OS << "(no argument)";
   }
 
   /// PrintTemplateTemplate - Handles printing of template template arguments,
@@ -1573,35 +1638,46 @@ class TemplateDiff {
     return true;
   }
 
+  void PrintValueDecl(ValueDecl *VD, bool AddressOf, bool NullPtr) {
+    if (VD) {
+      if (AddressOf)
+        OS << "&";
+      OS << VD->getName();
+      return;
+    }
+
+    if (NullPtr) {
+      OS << "nullptr";
+      return;
+    }
+
+    OS << "(no argument)";
+  }
+
   /// PrintDecl - Handles printing of Decl arguments, highlighting
   /// argument differences.
   void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
-                      bool FromAddressOf, bool ToAddressOf, bool FromDefault,
-                      bool ToDefault, bool Same) {
-    assert((FromValueDecl || ToValueDecl) &&
+                      bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,
+                      bool ToNullPtr, bool FromDefault, bool ToDefault,
+                      bool Same) {
+    assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
            "Only one Decl argument may be NULL");
 
     if (Same) {
-      OS << FromValueDecl->getName();
+      PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
     } else if (!PrintTree) {
       OS << (FromDefault ? "(default) " : "");
       Bold();
-      if (FromAddressOf)
-        OS << "&";
-      OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+      PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
       Unbold();
     } else {
       OS << (FromDefault ? "[(default) " : "[");
       Bold();
-      if (FromAddressOf)
-        OS << "&";
-      OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+      PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
       Unbold();
       OS << " != " << (ToDefault ? "(default) " : "");
       Bold();
-      if (ToAddressOf)
-        OS << "&";
-      OS << (ToValueDecl ? ToValueDecl->getName() : "(no argument)");
+      PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr);
       Unbold();
       OS << ']';
     }

Modified: cfe/branches/release_35/test/Misc/diag-template-diffing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_35/test/Misc/diag-template-diffing.cpp?rev=214693&r1=214692&r2=214693&view=diff
==============================================================================
--- cfe/branches/release_35/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/branches/release_35/test/Misc/diag-template-diffing.cpp Sun Aug  3 23:35:31 2014
@@ -1129,6 +1129,60 @@ Wrapper<S<(&global2)>> W4 = MakeWrapper<
 // CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<&global2>>'
 }
 
+namespace NullPtr {
+template <int*, int*>
+struct S {};
+
+template <class T>
+struct Wrapper {};
+
+template <class T>
+Wrapper<T> MakeWrapper();
+int global, global2;
+constexpr int * ptr = nullptr;
+constexpr int * ptr2 = static_cast<int*>(0);
+
+S<&global> s1 = S<&global, ptr>();
+S<&global, nullptr> s2 = S<&global, ptr>();
+
+S<&global, nullptr> s3 = S<&global, &global>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'S<[...], &global>' to 'S<[...], nullptr>'
+S<&global, ptr> s4 = S<&global, &global>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'S<[...], &global>' to 'S<[...], ptr>
+
+Wrapper<S<&global, nullptr>> W1 = MakeWrapper<S<&global, ptr>>();
+Wrapper<S<&global, static_cast<int*>(0)>> W2 = MakeWrapper<S<&global, ptr>>();
+
+Wrapper<S<&global, nullptr>> W3 = MakeWrapper<S<&global, &global>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], nullptr>>'
+Wrapper<S<&global, ptr>> W4 = MakeWrapper<S<&global, &global>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], ptr>>'
+
+Wrapper<S<&global2, ptr>> W5 = MakeWrapper<S<&global, nullptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, nullptr>> W6 = MakeWrapper<S<&global, nullptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, ptr2>> W7 = MakeWrapper<S<&global, nullptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, nullptr>> W8 = MakeWrapper<S<&global, ptr2>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, ptr>> W9 = MakeWrapper<S<&global, ptr2>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, ptr2>> W10 = MakeWrapper<S<&global, ptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, static_cast<int *>(0)>> W11 =
+    MakeWrapper<S<&global, nullptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, nullptr>> W12 =
+    MakeWrapper<S<&global, static_cast<int *>(0)>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+
+Wrapper<S<&global, &global>> W13 = MakeWrapper<S<&global, ptr>>();
+// C HECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], nullptr>>' to 'Wrapper<S<[...], &global>>'
+Wrapper<S<&global, ptr>> W14 = MakeWrapper<S<&global, &global>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], ptr>>'
+}
+
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.





More information about the llvm-branch-commits mailing list