@@ -4894,41 +4894,51 @@ static bool CheckConvertedConstantConversions(Sema &S,
48944894 // conversions are fine.
48954895 switch (SCS.Second ) {
48964896 case ICK_Identity:
4897+ case ICK_NoReturn_Adjustment:
48974898 case ICK_Integral_Promotion:
4898- case ICK_Integral_Conversion:
4899- case ICK_Zero_Event_Conversion:
4899+ case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere.
49004900 return true ;
49014901
49024902 case ICK_Boolean_Conversion:
49034903 // Conversion from an integral or unscoped enumeration type to bool is
4904- // classified as ICK_Boolean_Conversion, but it's also an integral
4905- // conversion, so it's permitted in a converted constant expression.
4904+ // classified as ICK_Boolean_Conversion, but it's also arguably an integral
4905+ // conversion, so we allow it in a converted constant expression.
4906+ //
4907+ // FIXME: Per core issue 1407, we should not allow this, but that breaks
4908+ // a lot of popular code. We should at least add a warning for this
4909+ // (non-conforming) extension.
49064910 return SCS.getFromType ()->isIntegralOrUnscopedEnumerationType () &&
49074911 SCS.getToType (2 )->isBooleanType ();
49084912
4913+ case ICK_Pointer_Conversion:
4914+ case ICK_Pointer_Member:
4915+ // C++1z: null pointer conversions and null member pointer conversions are
4916+ // only permitted if the source type is std::nullptr_t.
4917+ return SCS.getFromType ()->isNullPtrType ();
4918+
4919+ case ICK_Floating_Promotion:
4920+ case ICK_Complex_Promotion:
4921+ case ICK_Floating_Conversion:
4922+ case ICK_Complex_Conversion:
49094923 case ICK_Floating_Integral:
4924+ case ICK_Compatible_Conversion:
4925+ case ICK_Derived_To_Base:
4926+ case ICK_Vector_Conversion:
4927+ case ICK_Vector_Splat:
49104928 case ICK_Complex_Real:
4929+ case ICK_Block_Pointer_Conversion:
4930+ case ICK_TransparentUnionConversion:
4931+ case ICK_Writeback_Conversion:
4932+ case ICK_Zero_Event_Conversion:
49114933 return false ;
49124934
49134935 case ICK_Lvalue_To_Rvalue:
49144936 case ICK_Array_To_Pointer:
49154937 case ICK_Function_To_Pointer:
4916- case ICK_NoReturn_Adjustment:
4938+ llvm_unreachable (" found a first conversion kind in Second" );
4939+
49174940 case ICK_Qualification:
4918- case ICK_Compatible_Conversion:
4919- case ICK_Vector_Conversion:
4920- case ICK_Vector_Splat:
4921- case ICK_Derived_To_Base:
4922- case ICK_Pointer_Conversion:
4923- case ICK_Pointer_Member:
4924- case ICK_Block_Pointer_Conversion:
4925- case ICK_Writeback_Conversion:
4926- case ICK_Floating_Promotion:
4927- case ICK_Complex_Promotion:
4928- case ICK_Complex_Conversion:
4929- case ICK_Floating_Conversion:
4930- case ICK_TransparentUnionConversion:
4931- llvm_unreachable (" unexpected second conversion kind" );
4941+ llvm_unreachable (" found a third conversion kind in Second" );
49324942
49334943 case ICK_Num_Conversion_Kinds:
49344944 break ;
@@ -4940,67 +4950,71 @@ static bool CheckConvertedConstantConversions(Sema &S,
49404950// / CheckConvertedConstantExpression - Check that the expression From is a
49414951// / converted constant expression of type T, perform the conversion and produce
49424952// / the converted expression, per C++11 [expr.const]p3.
4943- ExprResult Sema::CheckConvertedConstantExpression (Expr *From, QualType T,
4944- llvm::APSInt &Value,
4945- CCEKind CCE) {
4946- assert (LangOpts.CPlusPlus11 && " converted constant expression outside C++11" );
4947- assert (T->isIntegralOrEnumerationType () && " unexpected converted const type" );
4948-
4949- if (checkPlaceholderForOverload (*this , From))
4953+ static ExprResult CheckConvertedConstantExpression (Sema &S, Expr *From,
4954+ QualType T, APValue &Value,
4955+ Sema::CCEKind CCE,
4956+ bool RequireInt) {
4957+ assert (S.getLangOpts ().CPlusPlus11 &&
4958+ " converted constant expression outside C++11" );
4959+
4960+ if (checkPlaceholderForOverload (S, From))
49504961 return ExprError ();
49514962
4952- // C++11 [expr.const]p3 with proposed wording fixes:
4953- // A converted constant expression of type T is a core constant expression,
4954- // implicitly converted to a prvalue of type T, where the converted
4955- // expression is a literal constant expression and the implicit conversion
4956- // sequence contains only user-defined conversions, lvalue-to-rvalue
4957- // conversions, integral promotions, and integral conversions other than
4958- // narrowing conversions.
4963+ // C++1z [expr.const]p3:
4964+ // A converted constant expression of type T is an expression,
4965+ // implicitly converted to type T, where the converted
4966+ // expression is a constant expression and the implicit conversion
4967+ // sequence contains only [... list of conversions ...].
49594968 ImplicitConversionSequence ICS =
4960- TryImplicitConversion ( From, T,
4969+ TryCopyInitialization (S, From, T,
49614970 /* SuppressUserConversions=*/ false ,
4962- /* AllowExplicit=*/ false ,
49634971 /* InOverloadResolution=*/ false ,
4964- /* CStyle =*/ false ,
4965- /* AllowObjcWritebackConversion =*/ false );
4972+ /* AllowObjcWritebackConversion =*/ false ,
4973+ /* AllowExplicit =*/ false );
49664974 StandardConversionSequence *SCS = nullptr ;
49674975 switch (ICS.getKind ()) {
49684976 case ImplicitConversionSequence::StandardConversion:
4969- if (!CheckConvertedConstantConversions (*this , ICS.Standard ))
4970- return Diag (From->getLocStart (),
4971- diag::err_typecheck_converted_constant_expression_disallowed)
4972- << From->getType () << From->getSourceRange () << T;
49734977 SCS = &ICS.Standard ;
49744978 break ;
49754979 case ImplicitConversionSequence::UserDefinedConversion:
4976- // We are converting from class type to an integral or enumeration type, so
4977- // the Before sequence must be trivial.
4978- if (!CheckConvertedConstantConversions (*this , ICS.UserDefined .After ))
4979- return Diag (From->getLocStart (),
4980- diag::err_typecheck_converted_constant_expression_disallowed)
4981- << From->getType () << From->getSourceRange () << T;
4980+ // We are converting to a non-class type, so the Before sequence
4981+ // must be trivial.
49824982 SCS = &ICS.UserDefined .After ;
49834983 break ;
49844984 case ImplicitConversionSequence::AmbiguousConversion:
49854985 case ImplicitConversionSequence::BadConversion:
4986- if (!DiagnoseMultipleUserDefinedConversion (From, T))
4987- return Diag (From->getLocStart (),
4988- diag::err_typecheck_converted_constant_expression)
4989- << From->getType () << From->getSourceRange () << T;
4986+ if (!S. DiagnoseMultipleUserDefinedConversion (From, T))
4987+ return S. Diag (From->getLocStart (),
4988+ diag::err_typecheck_converted_constant_expression)
4989+ << From->getType () << From->getSourceRange () << T;
49904990 return ExprError ();
49914991
49924992 case ImplicitConversionSequence::EllipsisConversion:
49934993 llvm_unreachable (" ellipsis conversion in converted constant expression" );
49944994 }
49954995
4996- ExprResult Result = PerformImplicitConversion (From, T, ICS, AA_Converting);
4996+ // Check that we would only use permitted conversions.
4997+ if (!CheckConvertedConstantConversions (S, *SCS)) {
4998+ return S.Diag (From->getLocStart (),
4999+ diag::err_typecheck_converted_constant_expression_disallowed)
5000+ << From->getType () << From->getSourceRange () << T;
5001+ }
5002+ // [...] and where the reference binding (if any) binds directly.
5003+ if (SCS->ReferenceBinding && !SCS->DirectBinding ) {
5004+ return S.Diag (From->getLocStart (),
5005+ diag::err_typecheck_converted_constant_expression_indirect)
5006+ << From->getType () << From->getSourceRange () << T;
5007+ }
5008+
5009+ ExprResult Result =
5010+ S.PerformImplicitConversion (From, T, ICS, Sema::AA_Converting);
49975011 if (Result.isInvalid ())
49985012 return Result;
49995013
50005014 // Check for a narrowing implicit conversion.
50015015 APValue PreNarrowingValue;
50025016 QualType PreNarrowingType;
5003- switch (SCS->getNarrowingKind (Context, Result.get (), PreNarrowingValue,
5017+ switch (SCS->getNarrowingKind (S. Context , Result.get (), PreNarrowingValue,
50045018 PreNarrowingType)) {
50055019 case NK_Variable_Narrowing:
50065020 // Implicit conversion to a narrower type, and the value is not a constant
@@ -5009,13 +5023,13 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
50095023 break ;
50105024
50115025 case NK_Constant_Narrowing:
5012- Diag (From->getLocStart (), diag::ext_cce_narrowing)
5026+ S. Diag (From->getLocStart (), diag::ext_cce_narrowing)
50135027 << CCE << /* Constant*/ 1
5014- << PreNarrowingValue.getAsString (Context, PreNarrowingType) << T;
5028+ << PreNarrowingValue.getAsString (S. Context , PreNarrowingType) << T;
50155029 break ;
50165030
50175031 case NK_Type_Narrowing:
5018- Diag (From->getLocStart (), diag::ext_cce_narrowing)
5032+ S. Diag (From->getLocStart (), diag::ext_cce_narrowing)
50195033 << CCE << /* Constant*/ 0 << From->getType () << T;
50205034 break ;
50215035 }
@@ -5025,12 +5039,15 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
50255039 Expr::EvalResult Eval;
50265040 Eval.Diag = &Notes;
50275041
5028- if (!Result.get ()->EvaluateAsRValue (Eval, Context) || !Eval.Val .isInt ()) {
5042+ if ((T->isReferenceType ()
5043+ ? !Result.get ()->EvaluateAsLValue (Eval, S.Context )
5044+ : !Result.get ()->EvaluateAsRValue (Eval, S.Context )) ||
5045+ (RequireInt && !Eval.Val .isInt ())) {
50295046 // The expression can't be folded, so we can't keep it at this position in
50305047 // the AST.
50315048 Result = ExprError ();
50325049 } else {
5033- Value = Eval.Val . getInt () ;
5050+ Value = Eval.Val ;
50345051
50355052 if (Notes.empty ()) {
50365053 // It's a constant expression.
@@ -5041,16 +5058,34 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
50415058 // It's not a constant expression. Produce an appropriate diagnostic.
50425059 if (Notes.size () == 1 &&
50435060 Notes[0 ].second .getDiagID () == diag::note_invalid_subexpr_in_const_expr)
5044- Diag (Notes[0 ].first , diag::err_expr_not_cce) << CCE;
5061+ S. Diag (Notes[0 ].first , diag::err_expr_not_cce) << CCE;
50455062 else {
5046- Diag (From->getLocStart (), diag::err_expr_not_cce)
5063+ S. Diag (From->getLocStart (), diag::err_expr_not_cce)
50475064 << CCE << From->getSourceRange ();
50485065 for (unsigned I = 0 ; I < Notes.size (); ++I)
5049- Diag (Notes[I].first , Notes[I].second );
5066+ S. Diag (Notes[I].first , Notes[I].second );
50505067 }
5051- return Result;
5068+ return ExprError ();
5069+ }
5070+
5071+ ExprResult Sema::CheckConvertedConstantExpression (Expr *From, QualType T,
5072+ APValue &Value, CCEKind CCE) {
5073+ return ::CheckConvertedConstantExpression (*this , From, T, Value, CCE, false );
5074+ }
5075+
5076+ ExprResult Sema::CheckConvertedConstantExpression (Expr *From, QualType T,
5077+ llvm::APSInt &Value,
5078+ CCEKind CCE) {
5079+ assert (T->isIntegralOrEnumerationType () && " unexpected converted const type" );
5080+
5081+ APValue V;
5082+ auto R = ::CheckConvertedConstantExpression (*this , From, T, V, CCE, true );
5083+ if (!R.isInvalid ())
5084+ Value = V.getInt ();
5085+ return R;
50525086}
50535087
5088+
50545089// / dropPointerConversions - If the given standard conversion sequence
50555090// / involves any pointer conversions, remove them. This may change
50565091// / the result type of the conversion sequence.
0 commit comments