<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Approved.<div><br><div><div>On May 8, 2013, at 4:23 PM, Richard Trieu <<a href="mailto:rtrieu@google.com">rtrieu@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir="ltr">Doug,<div><br></div><div>I'd like to get this into 3.3 since it fixes a crash on invalid.</div><div><br></div><div>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 class="Apple-converted-space"> </span><span dir="ltr"><<a href="mailto:rtrieu@google.com" target="_blank">rtrieu@google.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">Author: rtrieu<br>Date: Tue May  7 16:36:24 2013<br>New Revision: 181365<br><br>URL:<span class="Apple-converted-space"> </span><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>   <span class="Apple-converted-space"> </span>cfe/trunk/lib/AST/ASTDiagnostic.cpp<br>   <span class="Apple-converted-space"> </span>cfe/trunk/test/Misc/diag-template-diffing.cpp<br><br>Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp<br>URL:<span class="Apple-converted-space"> </span><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>                       <span class="Apple-converted-space"> </span>FromValueDecl->getCanonicalDecl() ==<br>                       <span class="Apple-converted-space"> </span>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>           <span class="Apple-converted-space"> </span>"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:<span class="Apple-converted-space"> </span><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></blockquote></div></div></div></blockquote></div><br></div></body></html>