<div dir="ltr">Doug,<div><br></div><div style>I'd like to get this into 3.3 since it fixes a crash on invalid.</div><div style><br></div><div style>Richard</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Tue, May 7, 2013 at 2:36 PM, Richard Trieu <span dir="ltr"><<a href="mailto:rtrieu@google.com" target="_blank">rtrieu@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: rtrieu<br>
Date: Tue May  7 16:36:24 2013<br>
New Revision: 181365<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=181365&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=181365&view=rev</a><br>
Log:<br>
Fix crash on invalid in template type diffing.<br>
<br>
This is a fix for PR15895, where Clang will crash when trying to print a<br>
template diff and the template uses an address of operator.  This resulted<br>
from expecting a DeclRefExpr when the Expr could have also been<br>
UnaryOperator->DeclRefExpr.<br>
<br>
Modified:<br>
    cfe/trunk/lib/AST/ASTDiagnostic.cpp<br>
    cfe/trunk/test/Misc/diag-template-diffing.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=181365&r1=181364&r2=181365&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=181365&r1=181364&r2=181365&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Tue May  7 16:36:24 2013<br>
@@ -459,6 +459,10 @@ class TemplateDiff {<br>
       /// FromValueDecl, ToValueDecl - Whether the argument is a decl.<br>
       ValueDecl *FromValueDecl, *ToValueDecl;<br>
<br>
+      /// FromAddressOf, ToAddressOf - Whether the ValueDecl needs an address of<br>
+      /// operator before it.<br>
+      bool FromAddressOf, ToAddressOf;<br>
+<br>
       /// FromDefault, ToDefault - Whether the argument is a default argument.<br>
       bool FromDefault, ToDefault;<br>
<br>
@@ -469,7 +473,8 @@ class TemplateDiff {<br>
         : Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),<br>
           FromType(), ToType(), FromExpr(0), ToExpr(0), FromTD(0), ToTD(0),<br>
           IsValidFromInt(false), IsValidToInt(false), FromValueDecl(0),<br>
-          ToValueDecl(0), FromDefault(false), ToDefault(false), Same(false) { }<br>
+          ToValueDecl(0), FromAddressOf(false), ToAddressOf(false),<br>
+          FromDefault(false), ToDefault(false), Same(false) { }<br>
     };<br>
<br>
     /// FlatTree - A flattened tree used to store the DiffNodes.<br>
@@ -526,9 +531,12 @@ class TemplateDiff {<br>
     }<br>
<br>
     /// SetNode - Set FromValueDecl and ToValueDecl of the current node.<br>
-    void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl) {<br>
+    void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,<br>
+                 bool FromAddressOf, bool ToAddressOf) {<br>
       FlatTree[CurrentNode].FromValueDecl = FromValueDecl;<br>
       FlatTree[CurrentNode].ToValueDecl = ToValueDecl;<br>
+      FlatTree[CurrentNode].FromAddressOf = FromAddressOf;<br>
+      FlatTree[CurrentNode].ToAddressOf = ToAddressOf;<br>
     }<br>
<br>
     /// SetSame - Sets the same flag of the current node.<br>
@@ -620,9 +628,12 @@ class TemplateDiff {<br>
     }<br>
<br>
     /// GetNode - Gets the FromValueDecl and ToValueDecl.<br>
-    void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl) {<br>
+    void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,<br>
+                 bool &FromAddressOf, bool &ToAddressOf) {<br>
       FromValueDecl = FlatTree[ReadNode].FromValueDecl;<br>
       ToValueDecl = FlatTree[ReadNode].ToValueDecl;<br>
+      FromAddressOf = FlatTree[ReadNode].FromAddressOf;<br>
+      ToAddressOf = FlatTree[ReadNode].ToAddressOf;<br>
     }<br>
<br>
     /// NodeIsSame - Returns true the arguments are the same.<br>
@@ -942,7 +953,14 @@ class TemplateDiff {<br>
             FromValueDecl = GetValueDecl(FromIter, FromExpr);<br>
           if (!HasToValueDecl && ToExpr)<br>
             ToValueDecl = GetValueDecl(ToIter, ToExpr);<br>
-          Tree.SetNode(FromValueDecl, ToValueDecl);<br>
+          QualType ArgumentType = DefaultNTTPD->getType();<br>
+          bool FromAddressOf = FromValueDecl &&<br>
+                               !ArgumentType->isReferenceType() &&<br>
+                               !FromValueDecl->getType()->isArrayType();<br>
+          bool ToAddressOf = ToValueDecl &&<br>
+                             !ArgumentType->isReferenceType() &&<br>
+                             !ToValueDecl->getType()->isArrayType();<br>
+          Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);<br>
           Tree.SetSame(FromValueDecl && ToValueDecl &&<br>
                        FromValueDecl->getCanonicalDecl() ==<br>
                        ToValueDecl->getCanonicalDecl());<br>
@@ -1080,7 +1098,7 @@ class TemplateDiff {<br>
     return ArgExpr->EvaluateKnownConstInt(Context);<br>
   }<br>
<br>
-  /// GetValueDecl - Retrieves the template integer argument, including<br>
+  /// GetValueDecl - Retrieves the template Decl argument, including<br>
   /// default expression argument.<br>
   ValueDecl *GetValueDecl(const TSTiterator &Iter, Expr *ArgExpr) {<br>
     // Default, value-depenedent expressions require fetching<br>
@@ -1095,7 +1113,12 @@ class TemplateDiff {<br>
         default:<br>
           assert(0 && "Unexpected template argument kind");<br>
       }<br>
-    return cast<DeclRefExpr>(ArgExpr)->getDecl();<br>
+    DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);<br>
+    if (!DRE) {<br>
+      DRE = cast<DeclRefExpr>(cast<UnaryOperator>(ArgExpr)->getSubExpr());<br>
+    }<br>
+<br>
+    return DRE->getDecl();<br>
   }<br>
<br>
   /// GetTemplateDecl - Retrieves the template template arguments, including<br>
@@ -1228,9 +1251,10 @@ class TemplateDiff {<br>
       }<br>
       case DiffTree::Declaration: {<br>
         ValueDecl *FromValueDecl, *ToValueDecl;<br>
-        Tree.GetNode(FromValueDecl, ToValueDecl);<br>
-        PrintValueDecl(FromValueDecl, ToValueDecl, Tree.FromDefault(),<br>
-                       Tree.ToDefault(), Tree.NodeIsSame());<br>
+        bool FromAddressOf, ToAddressOf;<br>
+        Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);<br>
+        PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,<br>
+                       Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());<br>
         return;<br>
       }<br>
       case DiffTree::Template: {<br>
@@ -1478,7 +1502,8 @@ class TemplateDiff {<br>
   /// PrintDecl - Handles printing of Decl arguments, highlighting<br>
   /// argument differences.<br>
   void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,<br>
-                      bool FromDefault, bool ToDefault, bool Same) {<br>
+                      bool FromAddressOf, bool ToAddressOf, bool FromDefault,<br>
+                      bool ToDefault, bool Same) {<br>
     assert((FromValueDecl || ToValueDecl) &&<br>
            "Only one Decl argument may be NULL");<br>
<br>
@@ -1487,15 +1512,21 @@ class TemplateDiff {<br>
     } else if (!PrintTree) {<br>
       OS << (FromDefault ? "(default) " : "");<br>
       Bold();<br>
+      if (FromAddressOf)<br>
+        OS << "&";<br>
       OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");<br>
       Unbold();<br>
     } else {<br>
       OS << (FromDefault ? "[(default) " : "[");<br>
       Bold();<br>
+      if (FromAddressOf)<br>
+        OS << "&";<br>
       OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");<br>
       Unbold();<br>
       OS << " != " << (ToDefault ? "(default) " : "");<br>
       Bold();<br>
+      if (ToAddressOf)<br>
+        OS << "&";<br>
       OS << (ToValueDecl ? ToValueDecl->getName() : "(no argument)");<br>
       Unbold();<br>
       OS << ']';<br>
<br>
Modified: cfe/trunk/test/Misc/diag-template-diffing.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=181365&r1=181364&r2=181365&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=181365&r1=181364&r2=181365&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)<br>
+++ cfe/trunk/test/Misc/diag-template-diffing.cpp Tue May  7 16:36:24 2013<br>
@@ -1002,6 +1002,33 @@ namespace VariadicDefault {<br>
   }<br>
 }<br>
<br>
+namespace PointerArguments {<br>
+  template <int *p> class T {};<br>
+  template <int* ...> class U {};<br>
+  int a, b, c;<br>
+  int z[5];<br>
+  void test() {<br>
+    T<&a> ta;<br>
+    T<z> tz;<br>
+    T<&b> tb(ta);<br>
+    // CHECK-ELIDE-NOTREE: no matching constructor for initialization of 'T<&b>'<br>
+    // CHECK-ELIDE-NOTREE: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'T<&a>' to 'const T<&b>' for 1st argument<br>
+    T<&c> tc(tz);<br>
+    // CHECK-ELIDE-NOTREE: no matching constructor for initialization of 'T<&c>'<br>
+    // CHECK-ELIDE-NOTREE: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'T<z>' to 'const T<&c>' for 1st argument<br>
+<br>
+    U<&a, &a> uaa;<br>
+    U<&b> ub(uaa);<br>
+    // CHECK-ELIDE-NOTREE: no matching constructor for initialization of 'U<&b>'<br>
+    // CHECK-ELIDE-NOTREE: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'U<&a, &a>' to 'const U<&b, (no argument)>' for 1st argument<br>

+<br>
+    U<&b, &b, &b> ubbb(uaa);<br>
+    // CHECK-ELIDE-NOTREE: no matching constructor for initialization of 'U<&b, &b, &b>'<br>
+    // CHECK-ELIDE-NOTREE: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'U<&a, &a, (no argument)>' to 'const U<&b, &b, &b>' for 1st argument<br>

+<br>
+  }<br>
+}<br>
+<br>
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.<br>
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.<br>
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>