]> granicus.if.org Git - clang/commitdiff
This patch fixes a crash after rebuilding call AST of
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 11 Nov 2014 16:56:21 +0000 (16:56 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 11 Nov 2014 16:56:21 +0000 (16:56 +0000)
an __unknown_anytype(...). In this case, we rebuild the
vararg function type specially to convert the call expression
to  something that IRGen can handle. However, FunctionDecl
as rebuilt in RebuildUnknownAnyExpr::resolveDecl is bogus and
results in crash when accessing its params later on. This
patch fixes the crash by rebuilding the FunctionDecl to match
its new resolved type. rdar://15297105.
(patch reapplied after lldb issue was fixed in r221660).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221691 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CodeGenCXX/unknown-anytype.cpp

index 5a4c7e6b778c5dc5df852d89a20e9b8d5b7502b2..37a08cfb0818a5f82b88f74ed9d0f768f0b38344 100644 (file)
@@ -13342,6 +13342,39 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
         << VD << E->getSourceRange();
       return ExprError();
     }
+    if (const FunctionProtoType *FT = Type->getAs<FunctionProtoType>()) {
+      // We must match the FunctionDecl's type to the hack introduced in
+      // RebuildUnknownAnyExpr::VisitCallExpr to vararg functions of unknown
+      // type. See the lengthy commentary in that routine.
+      QualType FDT = FD->getType();
+      const FunctionType *FnType = FDT->castAs<FunctionType>();
+      const FunctionProtoType *Proto = dyn_cast_or_null<FunctionProtoType>(FnType);
+      DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
+      if (DRE && Proto && Proto->getParamTypes().empty() && Proto->isVariadic()) {
+        SourceLocation Loc = FD->getLocation();
+        FunctionDecl *NewFD = FunctionDecl::Create(FD->getASTContext(),
+                                      FD->getDeclContext(),
+                                      Loc, Loc, FD->getNameInfo().getName(),
+                                      DestType, FD->getTypeSourceInfo(),
+                                      SC_None, false/*isInlineSpecified*/,
+                                      FD->hasPrototype(),
+                                      false/*isConstexprSpecified*/);
+          
+        if (FD->getQualifier())
+          NewFD->setQualifierInfo(FD->getQualifierLoc());
+
+        SmallVector<ParmVarDecl*, 16> Params;
+        for (const auto &AI : FT->param_types()) {
+          ParmVarDecl *Param =
+            S.BuildParmVarDeclForTypedef(FD, Loc, AI);
+          Param->setScopeInfo(0, Params.size());
+          Params.push_back(Param);
+        }
+        NewFD->setParams(Params);
+        DRE->setDecl(NewFD);
+        VD = DRE->getDecl();
+      }
+    }
 
     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
       if (MD->isInstance()) {
index aacb8493ef3c90ca890baf51719e5656a14ec4da..c1b8c7df708917f77d8bda012820ebaa53d3c460 100644 (file)
@@ -115,3 +115,9 @@ extern "C" __unknown_anytype test10_any(...);
 void test10() {
   (void) test10_any(), (void) test10_any();
 }
+
+extern "C" __unknown_anytype malloc(...);
+void test11() {
+  void *s = (void*)malloc(12);
+  void *d = (void*)malloc(435);
+}