On Mon, Jan 30, 2012 at 2:27 PM, Richard Smith <[email protected]> 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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
