diff options
author | George Burgess IV <george.burgess.iv@gmail.com> | 2015-12-02 21:58:08 +0000 |
---|---|---|
committer | George Burgess IV <george.burgess.iv@gmail.com> | 2015-12-02 21:58:08 +0000 |
commit | 3e3bb95b6951c313dd5dd1c099184c309a3952e2 (patch) | |
tree | 601f182e5509276b9319182864eac0e27a888b68 /clang/lib/Sema/SemaInit.cpp | |
parent | ba904d4ecf66528be5dadd60665d5a979ce6b1a4 (diff) | |
download | bcm5719-llvm-3e3bb95b6951c313dd5dd1c099184c309a3952e2.tar.gz bcm5719-llvm-3e3bb95b6951c313dd5dd1c099184c309a3952e2.zip |
Add the `pass_object_size` attribute to clang.
`pass_object_size` is our way of enabling `__builtin_object_size` to
produce high quality results without requiring inlining to happen
everywhere.
A link to the design doc for this attribute is available at the
Differential review link below.
Differential Revision: http://reviews.llvm.org/D13263
llvm-svn: 254554
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 461b3b648dc..89d253981c5 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3011,6 +3011,7 @@ bool InitializationSequence::isAmbiguous() const { case FK_VariableLengthArrayHasInitializer: case FK_PlaceholderType: case FK_ExplicitConstructor: + case FK_AddressOfUnaddressableFunction: return false; case FK_ReferenceInitOverloadFailed: @@ -4801,6 +4802,17 @@ InitializationSequence::InitializationSequence(Sema &S, InitializeFrom(S, Entity, Kind, Args, TopLevelOfInitList); } +/// Tries to get a FunctionDecl out of `E`. If it succeeds and we can take the +/// address of that function, this returns true. Otherwise, it returns false. +static bool isExprAnUnaddressableFunction(Sema &S, const Expr *E) { + auto *DRE = dyn_cast<DeclRefExpr>(E); + if (!DRE || !isa<FunctionDecl>(DRE->getDecl())) + return false; + + return !S.checkAddressOfFunctionIsAvailable( + cast<FunctionDecl>(DRE->getDecl())); +} + void InitializationSequence::InitializeFrom(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, @@ -4982,7 +4994,7 @@ void InitializationSequence::InitializeFrom(Sema &S, } assert(S.getLangOpts().CPlusPlus); - + // - If the destination type is a (possibly cv-qualified) class type: if (DestType->isRecordType()) { // - If the initialization is direct-initialization, or if it is @@ -5079,6 +5091,9 @@ void InitializationSequence::InitializeFrom(Sema &S, !S.ResolveAddressOfOverloadedFunction(Initializer, DestType, false, dap)) SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); + else if (Initializer->getType()->isFunctionType() && + isExprAnUnaddressableFunction(S, Initializer)) + SetFailed(InitializationSequence::FK_AddressOfUnaddressableFunction); else SetFailed(InitializationSequence::FK_ConversionFailed); } else { @@ -6926,6 +6941,13 @@ bool InitializationSequence::Diagnose(Sema &S, break; } + case FK_AddressOfUnaddressableFunction: { + auto *FD = cast<FunctionDecl>(cast<DeclRefExpr>(Args[0])->getDecl()); + S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, + Args[0]->getLocStart()); + break; + } + case FK_ReferenceInitOverloadFailed: case FK_UserConversionOverloadFailed: switch (FailedOverloadResult) { @@ -7248,6 +7270,10 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "array requires initializer list"; break; + case FK_AddressOfUnaddressableFunction: + OS << "address of unaddressable function was taken"; + break; + case FK_ArrayNeedsInitListOrStringLiteral: OS << "array requires initializer list or string literal"; break; |