aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-09-30 00:45:47 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-09-30 00:45:47 +0000
commit55dec868977ccb89cab0286122f9345f63bb5de7 (patch)
tree4bed8d8a28dc736f941396661c0e9f01541190a5
parent7426f793844407021ffeb5afcf917fff1a57f196 (diff)
constexpr functions are implicitly const. More tests to follow.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140831 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Decl.h4
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td8
-rw-r--r--lib/Sema/SemaType.cpp14
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp8
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp4
-rw-r--r--test/SemaCXX/cxx0x-cursory-default-delete.cpp2
6 files changed, 30 insertions, 10 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 841aa3b59c..7ba2668107 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -1794,8 +1794,8 @@ public:
}
/// \brief Determine whether this function should be inlined, because it is
- /// either marked "inline" or is a member function of a C++ class that
- /// was defined in the class body.
+ /// either marked "inline" or "constexpr" or is a member function of a class
+ /// that was defined in the class body.
bool isInlined() const;
bool isInlineDefinitionExternallyVisible() const;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 5330fb3956..1b974b0c02 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4292,8 +4292,8 @@ def err_defaulted_copy_assign_const_param : Error<
"the parameter for this explicitly-defaulted copy assignment operator is "
"const, but a member or base requires it to be non-const">;
def err_defaulted_copy_assign_quals : Error<
- "an explicitly-defaulted copy assignment operator may not have 'const' "
- "or 'volatile' qualifiers">;
+ "an explicitly-defaulted copy assignment operator may not have 'const', "
+ "'constexpr' or 'volatile' qualifiers">;
def err_defaulted_move_ctor_params : Error<
"an explicitly-defaulted move constructor must have exactly one parameter">;
def err_defaulted_move_ctor_volatile_param : Error<
@@ -4318,8 +4318,8 @@ def err_defaulted_move_assign_const_param : Error<
"the parameter for an explicitly-defaulted move assignment operator may not "
"be const">;
def err_defaulted_move_assign_quals : Error<
- "an explicitly-defaulted move assignment operator may not have 'const' "
- "or 'volatile' qualifiers">;
+ "an explicitly-defaulted move assignment operator may not have 'const', "
+ "'constexpr' or 'volatile' qualifiers">;
def err_incorrect_defaulted_exception_spec : Error<
"exception specification of explicitly defaulted %select{default constructor|"
"copy constructor|move constructor|copy assignment operator|move assignment "
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 85112dbe21..480dd3b85a 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2325,6 +2325,20 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
FreeFunction = (DC && !DC->isRecord());
}
+ // C++0x [dcl.constexpr]p8: A constexpr specifier for a non-static member
+ // function that is not a constructor declares that function to be const.
+ if (D.getDeclSpec().isConstexprSpecified() && !FreeFunction &&
+ D.getName().getKind() != UnqualifiedId::IK_ConstructorName &&
+ D.getName().getKind() != UnqualifiedId::IK_ConstructorTemplateId &&
+ !(FnTy->getTypeQuals() & DeclSpec::TQ_const)) {
+ // Rebuild function type adding a 'const' qualifier.
+ FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo();
+ EPI.TypeQuals |= DeclSpec::TQ_const;
+ T = Context.getFunctionType(FnTy->getResultType(),
+ FnTy->arg_type_begin(),
+ FnTy->getNumArgs(), EPI);
+ }
+
// C++0x [dcl.fct]p6:
// A ref-qualifier shall only be part of the function type for a
// non-static member function, the function type to which a pointer to
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp
index 25470779e6..77a3e26de4 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp
@@ -3,6 +3,7 @@
// constexpr functions and constexpr constructors are implicitly inline.
struct S {
constexpr S(int n);
+ constexpr int g();
int n;
};
@@ -12,9 +13,14 @@ constexpr S f(S s) {
return s.n * 2;
}
+constexpr int S::g() {
+ return f(*this).n;
+}
+
// CHECK: define linkonce_odr {{.*}} @_Z1f1S(
// CHECK: define linkonce_odr {{.*}} @_ZN1SC1Ei(
+// CHECK: define linkonce_odr {{.*}} @_ZNK1S1gEv(
int g() {
- return f(42).n;
+ return f(42).g();
}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp
index 6b964dba31..55adbf0c12 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp
@@ -22,7 +22,7 @@ namespace move {
};
struct ConstAssignment {
- ConstAssignment& operator=(ConstAssignment&&) const = default; // expected-error {{an explicitly-defaulted move assignment operator may not have 'const' or 'volatile' qualifiers}}
+ ConstAssignment& operator=(ConstAssignment&&) const = default; // expected-error {{an explicitly-defaulted move assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
};
}
@@ -57,6 +57,6 @@ namespace copy {
};
struct ConstAssignment {
- ConstAssignment& operator=(const ConstAssignment&) const = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}}
+ ConstAssignment& operator=(const ConstAssignment&) const = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
};
}
diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
index 61aee0e456..9d4443c887 100644
--- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp
+++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -35,7 +35,7 @@ struct bad_decls {
bad_decls(volatile bad_decls&) = default; // expected-error {{may not be volatile}}
bad_decls&& operator = (bad_decls) = default; // expected-error 2{{lvalue reference}}
bad_decls& operator = (volatile bad_decls&) = default; // expected-error {{may not be volatile}}
- bad_decls& operator = (const bad_decls&) const = default; // expected-error {{may not have 'const' or 'volatile' qualifiers}}
+ bad_decls& operator = (const bad_decls&) const = default; // expected-error {{may not have 'const', 'constexpr' or 'volatile' qualifiers}}
};
struct A {}; struct B {};