Author: rsmith Date: Thu Oct 3 11:55:23 2019 New Revision: 373648 URL: http://llvm.org/viewvc/llvm-project?rev=373648&view=rev Log: Check for qualified function types after substituting into the operand of 'typeid'.
This is a rare place where it's valid for a function type to be substituted but not valid for a qualified function type to be substituted, so needs a special check. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=373648&r1=373647&r2=373648&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Oct 3 11:55:23 2019 @@ -6211,6 +6211,8 @@ def err_invalid_qualified_function_type def err_compound_qualified_function_type : Error< "%select{block pointer|pointer|reference}0 to function type %select{%2 |}1" "cannot have '%3' qualifier">; +def err_qualified_function_typeid : Error< + "type operand %0 of 'typeid' cannot have '%1' qualifier">; def err_ref_qualifier_overload : Error< "cannot overload a member function %select{without a ref-qualifier|with " Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=373648&r1=373647&r2=373648&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Thu Oct 3 11:55:23 2019 @@ -1522,6 +1522,8 @@ public: QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace, SourceLocation AttrLoc); + bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc); + bool CheckFunctionReturnType(QualType T, SourceLocation Loc); /// Build a function type. Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=373648&r1=373647&r2=373648&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Oct 3 11:55:23 2019 @@ -453,6 +453,9 @@ ExprResult Sema::BuildCXXTypeId(QualType if (T->isVariablyModifiedType()) return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T); + if (CheckQualifiedFunctionForTypeId(T, TypeidLoc)) + return ExprError(); + return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand, SourceRange(TypeidLoc, RParenLoc)); } Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=373648&r1=373647&r2=373648&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Thu Oct 3 11:55:23 2019 @@ -1955,7 +1955,8 @@ static bool checkQualifiedFunction(Sema QualifiedFunctionKind QFK) { // Does T refer to a function type with a cv-qualifier or a ref-qualifier? const FunctionProtoType *FPT = T->getAs<FunctionProtoType>(); - if (!FPT || (FPT->getMethodQuals().empty() && FPT->getRefQualifier() == RQ_None)) + if (!FPT || + (FPT->getMethodQuals().empty() && FPT->getRefQualifier() == RQ_None)) return false; S.Diag(Loc, diag::err_compound_qualified_function_type) @@ -1964,6 +1965,17 @@ static bool checkQualifiedFunction(Sema return true; } +bool Sema::CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc) { + const FunctionProtoType *FPT = T->getAs<FunctionProtoType>(); + if (!FPT || + (FPT->getMethodQuals().empty() && FPT->getRefQualifier() == RQ_None)) + return false; + + Diag(Loc, diag::err_qualified_function_typeid) + << T << getFunctionQualifiersAsString(FPT); + return true; +} + /// Build a pointer type. /// /// \param T The type to which we'll be building a pointer. Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp?rev=373648&r1=373647&r2=373648&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp (original) +++ cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp Thu Oct 3 11:55:23 2019 @@ -192,6 +192,13 @@ struct TypeId0 { } }; +template<typename T> +struct TypeId1 { + const std::type_info &f() { + return typeid(T); // expected-error-re 2{{type operand 'void () {{const|&}}' of 'typeid' cannot have '{{const|&}}' qualifier}} + } +}; + struct Abstract { virtual void f() = 0; }; @@ -199,6 +206,8 @@ struct Abstract { template struct TypeId0<int>; template struct TypeId0<Incomplete>; // expected-note{{instantiation of member function}} template struct TypeId0<Abstract>; +template struct TypeId1<void() const>; // expected-note{{instantiation of}} +template struct TypeId1<void() &>; // expected-warning 0-1{{C++11}} expected-note{{instantiation of}} // --------------------------------------------------------------------- // type traits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits