From: Fariborz Jahanian Date: Tue, 11 Nov 2014 16:56:21 +0000 (+0000) Subject: This patch fixes a crash after rebuilding call AST of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d45e22102f8702a5280f100ebf0c503d65590321;p=clang This patch fixes a crash after rebuilding call AST of 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 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5a4c7e6b77..37a08cfb08 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -13342,6 +13342,39 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { << VD << E->getSourceRange(); return ExprError(); } + if (const FunctionProtoType *FT = Type->getAs()) { + // 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(); + const FunctionProtoType *Proto = dyn_cast_or_null(FnType); + DeclRefExpr *DRE = dyn_cast(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 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(FD)) if (MD->isInstance()) { diff --git a/test/CodeGenCXX/unknown-anytype.cpp b/test/CodeGenCXX/unknown-anytype.cpp index aacb8493ef..c1b8c7df70 100644 --- a/test/CodeGenCXX/unknown-anytype.cpp +++ b/test/CodeGenCXX/unknown-anytype.cpp @@ -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); +}