diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 1f2fa6fc6f44..b935ff0f2980 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -622,6 +622,9 @@ DIAG(err_expr_not_ice, ERROR, DIAG(ext_expr_not_ice, EXTENSION, "expression is not integer constant expression " "(but is allowed as an extension)") +DIAG(ext_null_pointer_expr_not_ice, EXTENSION, + "null pointer expression is not an integer constant expression " + "(but is allowed as an extension)") DIAG(note_comma_in_ice, NOTE, "C does not permit evaluated commas in an integer constant expression") @@ -965,8 +968,6 @@ DIAG(ext_enum_value_not_int, EXTENSION, "ISO C restricts enumerator values to range of 'int' (%0 is too large)") DIAG(warn_enum_too_large, WARNING, "enumeration values exceed range of largest integer") -DIAG(err_case_label_not_integer_constant_expr, ERROR, - "case label does not reduce to an integer constant") DIAG(warn_illegal_constant_array_size, EXTENSION, "size of static array must be an integer constant expression") DIAG(err_typecheck_illegal_vla, ERROR, diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 7b69de5cc242..17af72ad9d84 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1350,7 +1350,9 @@ public: /// VerifyIntegerConstantExpression - verifies that an expression is an ICE, /// and reports the appropriate diagnostics. Returns false on success. /// Can optionally return the value of the expression. - bool VerifyIntegerConstantExpression(const Expr* E, llvm::APSInt *Result = 0); + bool VerifyIntegerConstantExpression(const Expr*E, llvm::APSInt *Result = 0); + + bool isNullPointerConstant(const Expr *E); //===--------------------------------------------------------------------===// // Extra semantic analysis beyond the C type system diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0c17c75fceb2..fa4b71b5bd75 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1582,13 +1582,13 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 // the type of the other operand." if ((lexT->isPointerType() || lexT->isBlockPointerType() || Context.isObjCObjectPointerType(lexT)) && - rex->isNullPointerConstant(Context)) { + isNullPointerConstant(rex)) { ImpCastExprToType(rex, lexT); // promote the null to a pointer. return lexT; } if ((rexT->isPointerType() || rexT->isBlockPointerType() || Context.isObjCObjectPointerType(rexT)) && - lex->isNullPointerConstant(Context)) { + isNullPointerConstant(lex)) { ImpCastExprToType(lex, rexT); // promote the null to a pointer. return rexT; } @@ -3706,3 +3706,23 @@ bool Sema::VerifyIntegerConstantExpression(const Expr* E, llvm::APSInt *Result) *Result = EvalResult.Val.getInt(); return false; } + +bool Sema::isNullPointerConstant(const Expr *E) +{ + Expr::EvalResult EvalResult; + + if (!E->isNullPointerConstant(EvalResult, Context)) + return false; + + if (EvalResult.Diag) { + Diag(E->getExprLoc(), diag::ext_null_pointer_expr_not_ice) << + E->getSourceRange(); + + // Print the reason it's not a constant. + if (Diags.getDiagnosticLevel(diag::ext_null_pointer_expr_not_ice) != + Diagnostic::Ignored) + Diag(EvalResult.DiagLoc, EvalResult.Diag); + } + + return true; +} diff --git a/clang/test/Sema/i-c-e3.c b/clang/test/Sema/i-c-e3.c index 31bb3f815047..c371f4a5cce5 100644 --- a/clang/test/Sema/i-c-e3.c +++ b/clang/test/Sema/i-c-e3.c @@ -1,3 +1,3 @@ -// RUN: clang %s -fsyntax-only -verify -pedantic +// RUN: clang %s -fsyntax-only -verify -pedantic-errors -int a() {int p; *(1 ? &p : (void*)(0 && (a(),1))) = 10;} // expected-error {{not assignable}} +int a() {int p; *(1 ? &p : (void*)(0 && (a(),1))) = 10;} // expected-error {{null pointer expression is not an integer constant expression (but is allowed as an extension)}} // expected-note{{C does not permit evaluated commas in an integer constant expression}}