r181365 - Fix crash on invalid in template type diffing.
Richard Trieu
rtrieu at google.com
Wed May 8 16:23:52 PDT 2013
Doug,
I'd like to get this into 3.3 since it fixes a crash on invalid.
Richard
On Tue, May 7, 2013 at 2:36 PM, Richard Trieu <rtrieu at google.com> wrote:
> Author: rtrieu
> Date: Tue May 7 16:36:24 2013
> New Revision: 181365
>
> URL: http://llvm.org/viewvc/llvm-project?rev=181365&view=rev
> Log:
> Fix crash on invalid in template type diffing.
>
> This is a fix for PR15895, where Clang will crash when trying to print a
> template diff and the template uses an address of operator. This resulted
> from expecting a DeclRefExpr when the Expr could have also been
> UnaryOperator->DeclRefExpr.
>
> Modified:
> cfe/trunk/lib/AST/ASTDiagnostic.cpp
> cfe/trunk/test/Misc/diag-template-diffing.cpp
>
> Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=181365&r1=181364&r2=181365&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
> +++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Tue May 7 16:36:24 2013
> @@ -459,6 +459,10 @@ class TemplateDiff {
> /// FromValueDecl, ToValueDecl - Whether the argument is a decl.
> ValueDecl *FromValueDecl, *ToValueDecl;
>
> + /// FromAddressOf, ToAddressOf - Whether the ValueDecl needs an
> address of
> + /// operator before it.
> + bool FromAddressOf, ToAddressOf;
> +
> /// FromDefault, ToDefault - Whether the argument is a default
> argument.
> bool FromDefault, ToDefault;
>
> @@ -469,7 +473,8 @@ class TemplateDiff {
> : Kind(Invalid), NextNode(0), ChildNode(0),
> ParentNode(ParentNode),
> FromType(), ToType(), FromExpr(0), ToExpr(0), FromTD(0),
> ToTD(0),
> IsValidFromInt(false), IsValidToInt(false), FromValueDecl(0),
> - ToValueDecl(0), FromDefault(false), ToDefault(false),
> Same(false) { }
> + ToValueDecl(0), FromAddressOf(false), ToAddressOf(false),
> + FromDefault(false), ToDefault(false), Same(false) { }
> };
>
> /// FlatTree - A flattened tree used to store the DiffNodes.
> @@ -526,9 +531,12 @@ class TemplateDiff {
> }
>
> /// SetNode - Set FromValueDecl and ToValueDecl of the current node.
> - void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl) {
> + void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
> + bool FromAddressOf, bool ToAddressOf) {
> FlatTree[CurrentNode].FromValueDecl = FromValueDecl;
> FlatTree[CurrentNode].ToValueDecl = ToValueDecl;
> + FlatTree[CurrentNode].FromAddressOf = FromAddressOf;
> + FlatTree[CurrentNode].ToAddressOf = ToAddressOf;
> }
>
> /// SetSame - Sets the same flag of the current node.
> @@ -620,9 +628,12 @@ class TemplateDiff {
> }
>
> /// GetNode - Gets the FromValueDecl and ToValueDecl.
> - void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl) {
> + void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
> + bool &FromAddressOf, bool &ToAddressOf) {
> FromValueDecl = FlatTree[ReadNode].FromValueDecl;
> ToValueDecl = FlatTree[ReadNode].ToValueDecl;
> + FromAddressOf = FlatTree[ReadNode].FromAddressOf;
> + ToAddressOf = FlatTree[ReadNode].ToAddressOf;
> }
>
> /// NodeIsSame - Returns true the arguments are the same.
> @@ -942,7 +953,14 @@ class TemplateDiff {
> FromValueDecl = GetValueDecl(FromIter, FromExpr);
> if (!HasToValueDecl && ToExpr)
> ToValueDecl = GetValueDecl(ToIter, ToExpr);
> - Tree.SetNode(FromValueDecl, ToValueDecl);
> + QualType ArgumentType = DefaultNTTPD->getType();
> + bool FromAddressOf = FromValueDecl &&
> + !ArgumentType->isReferenceType() &&
> + !FromValueDecl->getType()->isArrayType();
> + bool ToAddressOf = ToValueDecl &&
> + !ArgumentType->isReferenceType() &&
> + !ToValueDecl->getType()->isArrayType();
> + Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf,
> ToAddressOf);
> Tree.SetSame(FromValueDecl && ToValueDecl &&
> FromValueDecl->getCanonicalDecl() ==
> ToValueDecl->getCanonicalDecl());
> @@ -1080,7 +1098,7 @@ class TemplateDiff {
> return ArgExpr->EvaluateKnownConstInt(Context);
> }
>
> - /// GetValueDecl - Retrieves the template integer argument, including
> + /// GetValueDecl - Retrieves the template Decl argument, including
> /// default expression argument.
> ValueDecl *GetValueDecl(const TSTiterator &Iter, Expr *ArgExpr) {
> // Default, value-depenedent expressions require fetching
> @@ -1095,7 +1113,12 @@ class TemplateDiff {
> default:
> assert(0 && "Unexpected template argument kind");
> }
> - return cast<DeclRefExpr>(ArgExpr)->getDecl();
> + DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
> + if (!DRE) {
> + DRE = cast<DeclRefExpr>(cast<UnaryOperator>(ArgExpr)->getSubExpr());
> + }
> +
> + return DRE->getDecl();
> }
>
> /// GetTemplateDecl - Retrieves the template template arguments,
> including
> @@ -1228,9 +1251,10 @@ class TemplateDiff {
> }
> case DiffTree::Declaration: {
> ValueDecl *FromValueDecl, *ToValueDecl;
> - Tree.GetNode(FromValueDecl, ToValueDecl);
> - PrintValueDecl(FromValueDecl, ToValueDecl, Tree.FromDefault(),
> - Tree.ToDefault(), Tree.NodeIsSame());
> + bool FromAddressOf, ToAddressOf;
> + Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf,
> ToAddressOf);
> + PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf,
> ToAddressOf,
> + Tree.FromDefault(), Tree.ToDefault(),
> Tree.NodeIsSame());
> return;
> }
> case DiffTree::Template: {
> @@ -1478,7 +1502,8 @@ class TemplateDiff {
> /// PrintDecl - Handles printing of Decl arguments, highlighting
> /// argument differences.
> void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
> - bool FromDefault, bool ToDefault, bool Same) {
> + bool FromAddressOf, bool ToAddressOf, bool
> FromDefault,
> + bool ToDefault, bool Same) {
> assert((FromValueDecl || ToValueDecl) &&
> "Only one Decl argument may be NULL");
>
> @@ -1487,15 +1512,21 @@ class TemplateDiff {
> } else if (!PrintTree) {
> OS << (FromDefault ? "(default) " : "");
> Bold();
> + if (FromAddressOf)
> + OS << "&";
> OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
> Unbold();
> } else {
> OS << (FromDefault ? "[(default) " : "[");
> Bold();
> + if (FromAddressOf)
> + OS << "&";
> OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
> Unbold();
> OS << " != " << (ToDefault ? "(default) " : "");
> Bold();
> + if (ToAddressOf)
> + OS << "&";
> OS << (ToValueDecl ? ToValueDecl->getName() : "(no argument)");
> Unbold();
> OS << ']';
>
> Modified: cfe/trunk/test/Misc/diag-template-diffing.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/diag-template-diffing.cpp?rev=181365&r1=181364&r2=181365&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/Misc/diag-template-diffing.cpp (original)
> +++ cfe/trunk/test/Misc/diag-template-diffing.cpp Tue May 7 16:36:24 2013
> @@ -1002,6 +1002,33 @@ namespace VariadicDefault {
> }
> }
>
> +namespace PointerArguments {
> + template <int *p> class T {};
> + template <int* ...> class U {};
> + int a, b, c;
> + int z[5];
> + void test() {
> + T<&a> ta;
> + T<z> tz;
> + T<&b> tb(ta);
> + // CHECK-ELIDE-NOTREE: no matching constructor for initialization of
> 'T<&b>'
> + // CHECK-ELIDE-NOTREE: candidate constructor (the implicit copy
> constructor) not viable: no known conversion from 'T<&a>' to 'const T<&b>'
> for 1st argument
> + T<&c> tc(tz);
> + // CHECK-ELIDE-NOTREE: no matching constructor for initialization of
> 'T<&c>'
> + // CHECK-ELIDE-NOTREE: candidate constructor (the implicit copy
> constructor) not viable: no known conversion from 'T<z>' to 'const T<&c>'
> for 1st argument
> +
> + U<&a, &a> uaa;
> + U<&b> ub(uaa);
> + // CHECK-ELIDE-NOTREE: no matching constructor for initialization of
> 'U<&b>'
> + // 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
> +
> + U<&b, &b, &b> ubbb(uaa);
> + // CHECK-ELIDE-NOTREE: no matching constructor for initialization of
> 'U<&b, &b, &b>'
> + // 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
> +
> + }
> +}
> +
> // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
> // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
> // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130508/607a7557/attachment.html>
More information about the cfe-commits
mailing list