-fms-compatibility: Use C++98 null pointer constant rules

Patch by Will Wilson!

llvm-svn: 194441
This commit is contained in:
Reid Kleckner 2013-11-12 02:22:34 +00:00
parent 0bc443b5c8
commit a5eef14eba
2 changed files with 24 additions and 2 deletions

View File

@ -3051,7 +3051,8 @@ bool Expr::hasNonTrivialCall(ASTContext &Ctx) {
Expr::NullPointerConstantKind
Expr::isNullPointerConstant(ASTContext &Ctx,
NullPointerConstantValueDependence NPC) const {
if (isValueDependent() && !Ctx.getLangOpts().CPlusPlus11) {
if (isValueDependent() &&
(!Ctx.getLangOpts().CPlusPlus11 || Ctx.getLangOpts().MicrosoftMode)) {
switch (NPC) {
case NPC_NeverValueDependent:
llvm_unreachable("Unexpected value dependent expression!");
@ -3133,8 +3134,13 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
if (Ctx.getLangOpts().CPlusPlus11) {
// C++11 [conv.ptr]p1: A null pointer constant is an integer literal with
// value zero or a prvalue of type std::nullptr_t.
// Microsoft mode permits C++98 rules reflecting MSVC behavior.
const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(this);
return (Lit && !Lit->getValue()) ? NPCK_ZeroLiteral : NPCK_NotNull;
if (Lit && !Lit->getValue())
return NPCK_ZeroLiteral;
else if (!Ctx.getLangOpts().MicrosoftMode ||
!isCXX98IntegralConstantExpr(Ctx))
return NPCK_NotNull;
} else {
// If we have an integer constant expression, we need to *evaluate* it and
// test for the value 0.

View File

@ -178,3 +178,19 @@ namespace PR11791 {
del((void*)a); // expected-note {{in instantiation of function template specialization}}
}
}
namespace IntToNullPtrConv {
struct Foo {
static const int ZERO = 0;
typedef void (Foo::*MemberFcnPtr)();
};
struct Bar {
const Foo::MemberFcnPtr pB;
};
Bar g_bar = { (Foo::MemberFcnPtr)Foo::ZERO };
template<int N> int *get_n() { return N; } // expected-warning {{expression which evaluates to zero treated as a null pointer constant}}
int *g_nullptr = get_n<0>(); // expected-note {{in instantiation of function template specialization}}
}