<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>