diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-10-03 18:55:23 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-10-03 18:55:23 +0000 |
| commit | 5d96b4ce288241f58372ef9d951216bf28996f57 (patch) | |
| tree | 6b534e84cef78bbd5f797a0ab0a0b8a9dfd12a2e /clang/lib/Sema | |
| parent | fb13e65acf0b7de3dd0b60b6312df07fdf9da652 (diff) | |
| download | bcm5719-llvm-5d96b4ce288241f58372ef9d951216bf28996f57.tar.gz bcm5719-llvm-5d96b4ce288241f58372ef9d951216bf28996f57.zip | |
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.
llvm-svn: 373648
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 14 |
2 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index abd8745277a..a25e86b95c3 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -453,6 +453,9 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, 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)); } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index a9459d97942..3029e148dc1 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1955,7 +1955,8 @@ static bool checkQualifiedFunction(Sema &S, QualType T, SourceLocation Loc, 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 &S, QualType T, SourceLocation Loc, 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. |

