[cfe-commits] r149286 - in /cfe/trunk: lib/AST/ExprConstant.cpp lib/Sema/SemaOverload.cpp test/CXX/expr/expr.const/p2-0x.cpp
Eli Friedman
eli.friedman at gmail.com
Mon Jan 30 16:29:27 PST 2012
On Mon, Jan 30, 2012 at 2:27 PM, Richard Smith
<richard-llvm at metafoo.co.uk> wrote:
> Author: rsmith
> Date: Mon Jan 30 16:27:01 2012
> New Revision: 149286
>
> URL: http://llvm.org/viewvc/llvm-project?rev=149286&view=rev
> Log:
> constexpr: disallow signed integer overflow in integral conversions in constant
> expressions in C++11.
Standard citation? As far as I can tell, the result of
(int)0x80000000u is implementation-defined, but it's still a constant
expression given how we define it.
-Eli
> Modified:
> cfe/trunk/lib/AST/ExprConstant.cpp
> cfe/trunk/lib/Sema/SemaOverload.cpp
> cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=149286&r1=149285&r2=149286&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Jan 30 16:27:01 2012
> @@ -1086,13 +1086,21 @@
> return true;
> }
>
> -static APSInt HandleIntToIntCast(QualType DestType, QualType SrcType,
> - APSInt &Value, const ASTContext &Ctx) {
> - unsigned DestWidth = Ctx.getIntWidth(DestType);
> +static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E,
> + QualType DestType, QualType SrcType,
> + APSInt &Value) {
> + unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
> APSInt Result = Value;
> // Figure out if this is a truncate, extend or noop cast.
> // If the input is signed, do a sign extend, noop, or truncate.
> Result = Result.extOrTrunc(DestWidth);
> +
> + // Check whether we overflowed. If so, fold the cast anyway.
> + if (DestType->isSignedIntegerOrEnumerationType() &&
> + ((Result.isNegative() && Value.isUnsigned()) ||
> + Result.extOrTrunc(Value.getBitWidth()) != Value))
> + (void)HandleOverflow(Info, E, Value, DestType);
> +
> Result.setIsUnsigned(DestType->isUnsignedIntegerOrEnumerationType());
> return Result;
> }
> @@ -4703,8 +4711,8 @@
> return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
> }
>
> - return Success(HandleIntToIntCast(DestType, SrcType,
> - Result.getInt(), Info.Ctx), E);
> + return Success(HandleIntToIntCast(Info, E, DestType, SrcType,
> + Result.getInt()), E);
> }
>
> case CK_PointerToIntegral: {
> @@ -4716,6 +4724,9 @@
>
> if (LV.getLValueBase()) {
> // Only allow based lvalue casts if they are lossless.
> + // FIXME: Allow a larger integer size than the pointer size, and allow
> + // narrowing back down to pointer width in subsequent integral casts.
> + // FIXME: Check integer type's active bits, not its type size.
> if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
> return Error(E);
>
> @@ -4726,7 +4737,7 @@
>
> APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(),
> SrcType);
> - return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E);
> + return Success(HandleIntToIntCast(Info, E, DestType, SrcType, AsInt), E);
> }
>
> case CK_IntegralComplexToReal: {
> @@ -5200,8 +5211,8 @@
> QualType From
> = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType();
>
> - Result.IntReal = HandleIntToIntCast(To, From, Result.IntReal, Info.Ctx);
> - Result.IntImag = HandleIntToIntCast(To, From, Result.IntImag, Info.Ctx);
> + Result.IntReal = HandleIntToIntCast(Info, E, To, From, Result.IntReal);
> + Result.IntImag = HandleIntToIntCast(Info, E, To, From, Result.IntImag);
> return true;
> }
>
>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=149286&r1=149285&r2=149286&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 30 16:27:01 2012
> @@ -4646,6 +4646,7 @@
>
> // Check for a narrowing implicit conversion.
> APValue PreNarrowingValue;
> + bool Diagnosed = false;
> switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue)) {
> case NK_Variable_Narrowing:
> // Implicit conversion to a narrower type, and the value is not a constant
> @@ -4657,11 +4658,13 @@
> Diag(From->getSourceRange().getBegin(), diag::err_cce_narrowing)
> << CCE << /*Constant*/1
> << PreNarrowingValue.getAsString(Context, QualType()) << T;
> + Diagnosed = true;
> break;
>
> case NK_Type_Narrowing:
> Diag(From->getSourceRange().getBegin(), diag::err_cce_narrowing)
> << CCE << /*Constant*/0 << From->getType() << T;
> + Diagnosed = true;
> break;
> }
>
> @@ -4674,12 +4677,19 @@
> // The expression can't be folded, so we can't keep it at this position in
> // the AST.
> Result = ExprError();
> - } else if (Notes.empty()) {
> - // It's a constant expression.
> + } else {
> Value = Eval.Val.getInt();
> - return Result;
> +
> + if (Notes.empty()) {
> + // It's a constant expression.
> + return Result;
> + }
> }
>
> + // Only issue one narrowing diagnostic.
> + if (Diagnosed)
> + return Result;
> +
> // It's not a constant expression. Produce an appropriate diagnostic.
> if (Notes.size() == 1 &&
> Notes[0].second.getDiagID() == diag::note_invalid_subexpr_in_const_expr)
> @@ -4690,7 +4700,7 @@
> for (unsigned I = 0; I < Notes.size(); ++I)
> Diag(Notes[I].first, Notes[I].second);
> }
> - return ExprError();
> + return Result;
> }
>
> /// dropPointerConversions - If the given standard conversion sequence
>
> 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=149286&r1=149285&r2=149286&view=diff
> ==============================================================================
> --- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
> +++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Mon Jan 30 16:27:01 2012
> @@ -118,6 +118,9 @@
> void f(int n) {
> switch (n) {
> case (int)4.4e9: // expected-error {{constant expression}} expected-note {{value 4.4E+9 is outside the range of representable values of type 'int'}}
> + case (int)10000000000ll: // expected-error {{constant expression}} expected-note {{value 10000000000 is outside the range of representable values of type 'int'}} expected-note {{here}}
> + case (int)0x80000000u: // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range of representable values of type 'int'}}
> + case (unsigned int)10000000000ll: // expected-error {{duplicate case value}}
> case (int)(unsigned)(long long)4.4e9: // ok
> case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}}
> case (int)((float)1e37 / 1e30): // ok
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list