From 7eddcff8fa2722bca96e38b7a01c1963e25a49cf Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Mon, 14 Sep 2015 07:05:00 +0000 Subject: [PATCH] [Sema] Reject value-initialization of function types T in the expression T() must be a non-array complete object type or the void type. Function types are neither. This fixes PR24798. llvm-svn: 247535 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/Sema/SemaExprCXX.cpp | 9 +++++++++ clang/test/SemaCXX/type-convert-construct.cpp | 2 ++ 3 files changed, 13 insertions(+) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 2fa7f01..49e5d69 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5219,6 +5219,8 @@ def err_builtin_func_cast_more_than_one_arg : Error< "function-style cast to a builtin type can only take one argument">; def err_value_init_for_array_type : Error< "array types cannot be value-initialized">; +def err_value_init_for_function_type : Error< + "function types cannot be value-initialized">; def warn_format_nonliteral_noargs : Warning< "format string is not a string literal (potentially insecure)">, InGroup; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index a48e634..f75ec70 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1031,6 +1031,11 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc); } + // C++14 [expr.type.conv]p2: The expression T(), where T is a + // simple-type-specifier or typename-specifier for a non-array complete + // object type or the (possibly cv-qualified) void type, creates a prvalue + // of the specified type, whose value is that produced by value-initializing + // an object of type T. QualType ElemTy = Ty; if (Ty->isArrayType()) { if (!ListInitialization) @@ -1039,6 +1044,10 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, ElemTy = Context.getBaseElementType(Ty); } + if (!ListInitialization && Ty->isFunctionType()) + return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_function_type) + << FullRange); + if (!Ty->isVoidType() && RequireCompleteType(TyBeginLoc, ElemTy, diag::err_invalid_incomplete_type_use, FullRange)) diff --git a/clang/test/SemaCXX/type-convert-construct.cpp b/clang/test/SemaCXX/type-convert-construct.cpp index 479af21..2dec50a 100644 --- a/clang/test/SemaCXX/type-convert-construct.cpp +++ b/clang/test/SemaCXX/type-convert-construct.cpp @@ -5,6 +5,8 @@ void f() { int v2 = typeof(int)(1,2); // expected-error {{excess elements in scalar initializer}} typedef int arr[]; int v3 = arr(); // expected-error {{array types cannot be value-initialized}} + typedef void fn_ty(); + fn_ty(); // expected-error {{function types cannot be value-initialized}} int v4 = int(); int v5 = int; // expected-error {{expected '(' for function-style cast or type construction}} typedef int T; -- 2.7.4