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