[cfe-commits] r150059 - in /cfe/trunk: include/clang/Basic/DiagnosticASTKinds.td lib/AST/ExprConstant.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/expr/expr.const/p2-0x.cpp test/SemaCXX/constexpr-sysheaders.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Tue Feb 7 22:14:53 PST 2012
Author: rsmith
Date: Wed Feb 8 00:14:53 2012
New Revision: 150059
URL: http://llvm.org/viewvc/llvm-project?rev=150059&view=rev
Log:
Implement the agreed resolution to DR1457: a signed left shift of a 1 bit into
the sign bit doesn't have undefined behavior, but a signed left shift of a 1 bit
out of the sign bit still does. As promised to Howard :)
The suppression of the potential constant expression checking in system headers
is also removed, since the problem it was working around is gone.
Removed:
cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=150059&r1=150058&r2=150059&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Wed Feb 8 00:14:53 2012
@@ -24,6 +24,7 @@
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">;
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=150059&r1=150058&r2=150059&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Feb 8 00:14:53 2012
@@ -4704,12 +4704,11 @@
<< 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);
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=150059&r1=150058&r2=150059&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Feb 8 00:14:53 2012
@@ -984,13 +984,8 @@
// 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<PartialDiagnosticAt, 8> 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<CXXConstructorDecl>(Dcl);
for (size_t I = 0, N = Diags.size(); I != N; ++I)
Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=150059&r1=150058&r2=150059&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Wed Feb 8 00:14:53 2012
@@ -144,8 +144,11 @@
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}}
Removed: cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp?rev=150058&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp (original)
+++ cfe/trunk/test/SemaCXX/constexpr-sysheaders.cpp (removed)
@@ -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
More information about the cfe-commits
mailing list