diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-20 02:18:31 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-20 02:18:31 +0000 |
commit | f032001b6e2f297a50502fe7aa545b12afa74cf2 (patch) | |
tree | 374a944ea3fd906aeb831575b78caa6f13ac3ba8 /clang/lib/Sema/SemaInit.cpp | |
parent | 763e591461c675dd785ba2311f9a2f1d5516a1af (diff) | |
download | bcm5719-llvm-f032001b6e2f297a50502fe7aa545b12afa74cf2.tar.gz bcm5719-llvm-f032001b6e2f297a50502fe7aa545b12afa74cf2.zip |
Add a workaround for a libstdc++-4.2 <tr1/hashtable> bug. This header uses
return false;
in a function returning a pointer. 'false' was a null pointer constant in C++98
but is not in C++11. Punch a very small hole in the initialization rules in
C++11 mode to allow this specific case in system headers.
llvm-svn: 184395
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 4e55da328a9..9d7fcda8fdd 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4135,6 +4135,24 @@ static void TryUserDefinedConversion(Sema &S, } } +/// An egregious hack for compatibility with libstdc++-4.2: in <tr1/hashtable>, +/// a function with a pointer return type contains a 'return false;' statement. +/// In C++11, 'false' is not a null pointer, so this breaks the build of any +/// code using that header. +/// +/// Work around this by treating 'return false;' as zero-initializing the result +/// if it's used in a pointer-returning function in a system header. +static bool isLibstdcxxPointerReturnFalseHack(Sema &S, + const InitializedEntity &Entity, + const Expr *Init) { + return S.getLangOpts().CPlusPlus11 && + Entity.getKind() == InitializedEntity::EK_Result && + Entity.getType()->isPointerType() && + isa<CXXBoolLiteralExpr>(Init) && + !cast<CXXBoolLiteralExpr>(Init)->getValue() && + S.getSourceManager().isInSystemHeader(Init->getExprLoc()); +} + /// The non-zero enum values here are indexes into diagnostic alternatives. enum InvalidICRKind { IIK_okay, IIK_nonlocal, IIK_nonscalar }; @@ -4571,9 +4589,11 @@ InitializationSequence::InitializationSequence(Sema &S, AddPassByIndirectCopyRestoreStep(Entity.getType(), ShouldCopy); } else if (ICS.isBad()) { DeclAccessPair dap; - if (Initializer->getType() == Context.OverloadTy && - !S.ResolveAddressOfOverloadedFunction(Initializer - , DestType, false, dap)) + if (isLibstdcxxPointerReturnFalseHack(S, Entity, Initializer)) { + AddZeroInitializationStep(Entity.getType()); + } else if (Initializer->getType() == Context.OverloadTy && + !S.ResolveAddressOfOverloadedFunction(Initializer, DestType, + false, dap)) SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); else SetFailed(InitializationSequence::FK_ConversionFailed); |