diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2014-11-11 16:56:21 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2014-11-11 16:56:21 +0000 |
| commit | a29986c0b074e241c04aa1d7ad96067c8c2e9158 (patch) | |
| tree | 70853182e1a8131b4031da9fd7304d83be3883a1 /clang/lib | |
| parent | f1ce9c177f3f5d09f0b4a36770d87825a131b167 (diff) | |
| download | bcm5719-llvm-a29986c0b074e241c04aa1d7ad96067c8c2e9158.tar.gz bcm5719-llvm-a29986c0b074e241c04aa1d7ad96067c8c2e9158.zip | |
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).
llvm-svn: 221691
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5a4c7e6b778..37a08cfb081 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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<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()) { |

