aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-07-12 23:11:43 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-07-12 23:11:43 +0000
commitf9ea1f392ab8946f7bfc3f98802a8e5e6fe073f3 (patch)
tree1cc02c3da0c1878ed30c5ecb0cccb388b48ef36f
parenta5c5babb9974aaf07568e90086af52b91edc2c16 (diff)
Produce an error on encountering a pointer or reference to a qualified function type. Fixes PR7470.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108209 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaDecl.cpp17
-rw-r--r--test/SemaCXX/function-type-qual.cpp5
3 files changed, 24 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 10121d8682..8fda370e05 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2157,6 +2157,8 @@ def err_invalid_member_use_in_static_method : Error<
"invalid use of member %0 in static member function">;
def err_invalid_qualified_function_type : Error<
"type qualifier is not allowed on this function">;
+def err_invalid_qualified_function_pointer : Error<
+ "type qualifier is not allowed on this function %select{pointer|reference}0">;
def err_invalid_qualified_typedef_function_type_use : Error<
"a qualified function type cannot be used to declare a "
"%select{static member|nonmember}0 function">;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 73de52476f..318ae494f1 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2861,6 +2861,23 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD,
return NewVD->setInvalidDecl();
}
+ // Function pointers and references cannot have qualified function type, only
+ // function pointer-to-members can do that.
+ QualType Pointee;
+ unsigned PtrOrRef = 0;
+ if (const PointerType *Ptr = T->getAs<PointerType>())
+ Pointee = Ptr->getPointeeType();
+ else if (const ReferenceType *Ref = T->getAs<ReferenceType>()) {
+ Pointee = Ref->getPointeeType();
+ PtrOrRef = 1;
+ }
+ if (!Pointee.isNull() && Pointee->isFunctionProtoType() &&
+ Pointee->getAs<FunctionProtoType>()->getTypeQuals() != 0) {
+ Diag(NewVD->getLocation(), diag::err_invalid_qualified_function_pointer)
+ << PtrOrRef;
+ return NewVD->setInvalidDecl();
+ }
+
if (!Previous.empty()) {
Redeclaration = true;
MergeVarDecl(NewVD, Previous);
diff --git a/test/SemaCXX/function-type-qual.cpp b/test/SemaCXX/function-type-qual.cpp
index ec27748900..8ebb506070 100644
--- a/test/SemaCXX/function-type-qual.cpp
+++ b/test/SemaCXX/function-type-qual.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
void f() const; // expected-error {{type qualifier is not allowed on this function}}
+void (*pf)() const; // expected-error {{type qualifier is not allowed on this function pointer}}
+void (&rf)() const = f; // expected-error {{type qualifier is not allowed on this function reference}}
typedef void cfn() const;
cfn f2; // expected-error {{a qualified function type cannot be used to declare a nonmember function}}
@@ -21,3 +23,6 @@ class C {
int x;
};
+
+void (C::*mpf)() const;
+cfn C::*mpg;