summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-20 02:18:31 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-20 02:18:31 +0000
commitf032001b6e2f297a50502fe7aa545b12afa74cf2 (patch)
tree374a944ea3fd906aeb831575b78caa6f13ac3ba8 /clang/lib/Sema/SemaInit.cpp
parent763e591461c675dd785ba2311f9a2f1d5516a1af (diff)
downloadbcm5719-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.cpp26
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);
OpenPOWER on IntegriCloud