diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index ce1ca5b03867..9e4b63cfe81c 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -24,6 +24,7 @@ def note_constexpr_negative_shift : Note<"negative shift count %0">; def note_constexpr_large_shift : Note< "shift count %0 >= width of type %1 (%2 bit%s2)">; def note_constexpr_lshift_of_negative : Note<"left shift of negative value %0">; +def note_constexpr_lshift_discards : Note<"signed left shift discards bits">; def note_constexpr_invalid_function : Note< "%select{non-constexpr|undefined}0 %select{function|constructor}1 %2 cannot " "be used in a constant expression">; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index e33d22a4aa35..410406788dc4 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -4704,12 +4704,11 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { << RHS << E->getType() << LHS.getBitWidth(); } else if (LHS.isSigned()) { // C++11 [expr.shift]p2: A signed left shift must have a non-negative - // operand, and must not overflow. + // operand, and must not overflow the corresponding unsigned type. if (LHS.isNegative()) CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS; - else if (LHS.countLeadingZeros() <= SA) - HandleOverflow(Info, E, LHS.extend(LHS.getBitWidth() + SA) << SA, - E->getType()); + else if (LHS.countLeadingZeros() < SA) + CCEDiag(E, diag::note_constexpr_lshift_discards); } return Success(LHS << SA, E); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 2c1642361b80..ca64af644f6f 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -984,13 +984,8 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body, // C++11 [dcl.constexpr]p4: // - every constructor involved in initializing non-static data members and // base class sub-objects shall be a constexpr constructor. - // - // FIXME: We currently disable this check inside system headers, to work - // around early STL implementations which contain constexpr functions which - // can't produce constant expressions. llvm::SmallVector Diags; - if (!Context.getSourceManager().isInSystemHeader(Dcl->getLocation()) && - !IsInstantiation && !Expr::isPotentialConstantExpr(Dcl, Diags)) { + if (!IsInstantiation && !Expr::isPotentialConstantExpr(Dcl, Diags)) { Diag(Dcl->getLocation(), diag::err_constexpr_function_never_constant_expr) << isa(Dcl); for (size_t I = 0, N = Diags.size(); I != N; ++I) diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp index 6c7a4947d783..71dc2f7104e4 100644 --- a/clang/test/CXX/expr/expr.const/p2-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp @@ -144,8 +144,11 @@ namespace UndefinedBehavior { constexpr int shl_unsigned_overflow = 1024u << 31; // ok constexpr int shl_signed_negative = (-3) << 1; // expected-error {{constant expression}} expected-note {{left shift of negative value -3}} constexpr int shl_signed_ok = 1 << 30; // ok - constexpr int shl_signed_into_sign = 1 << 31; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}} - constexpr int shl_signed_overflow = 1024 << 31; // expected-error {{constant expression}} expected-note {{value 2199023255552 is outside the range}} expected-warning {{requires 43 bits to represent}} + constexpr int shl_signed_into_sign = 1 << 31; // ok (DR1457) + constexpr int shl_signed_into_sign_2 = 0x7fffffff << 1; // ok (DR1457) + constexpr int shl_signed_off_end = 2 << 31; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{signed shift result (0x100000000) requires 34 bits to represent, but 'int' only has 32 bits}} + constexpr int shl_signed_off_end_2 = 0x7fffffff << 2; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{signed shift result (0x1FFFFFFFC) requires 34 bits to represent, but 'int' only has 32 bits}} + constexpr int shl_signed_overflow = 1024 << 31; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{requires 43 bits to represent}} constexpr int shl_signed_ok2 = 1024 << 20; // ok constexpr int shr_m1 = 0 >> -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}} diff --git a/clang/test/SemaCXX/constexpr-sysheaders.cpp b/clang/test/SemaCXX/constexpr-sysheaders.cpp deleted file mode 100644 index 5f9a712bc762..000000000000 --- a/clang/test/SemaCXX/constexpr-sysheaders.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -include %s %s - -// libstdc++4.6 has a broken numeric_limits with a non-constant min() for signed -// integral types. Disable the 'never produces a constant expression' error in -// system headers to work around it. We still won't treat the function as -// producing a constant expression, though. - -#ifndef INCLUDED_HEADER -#define INCLUDED_HEADER - -#pragma GCC system_header - -// An approximation of libstdc++4.6's broken definition of numeric_limits. -// FIXME: In the -include case, the line numbers are off by one for some reason! -struct numeric_limits { // expected-note {{value 2147483648 is outside the range}} - static constexpr int min() throw() { return (int)1 << (sizeof(int) * 8 - 1); } // no-error - // expected-note {{in call to 'min()'}} - static constexpr int lowest() throw() { return min(); } -}; - -#else - -constexpr int k = numeric_limits::lowest(); // expected-error {{constant expression}} expected-note {{in call to 'lowest()'}} - -#endif