From c3eba8f547c7079a79e321e8f18893b80b52f413 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Wed, 9 Jun 2010 21:19:43 +0000 Subject: [PATCH] Commit my WIP on constexpr support. This commit: an XFAILed test and treating constexpr as a top-level const. llvm-svn: 105752 --- clang/lib/Sema/SemaType.cpp | 7 +- .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 78 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 8327fd268647..bec929dabf0e 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -860,7 +860,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, T = Context.getCanonicalType(T); } - // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member + // C++ 8.3.3p3: A pointer to member shall not point to ... a member // with reference type, or "cv void." if (T->isReferenceType()) { Diag(Loc, diag::err_illegal_decl_mempointer_to_reference) @@ -1335,6 +1335,11 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, } } + // If there's a constexpr specifier, treat it as a top-level const. + if (D.getDeclSpec().isConstexprSpecified()) { + T.addConst(); + } + // Process any function attributes we might have delayed from the // declaration-specifiers. ProcessDelayedFnAttrs(*this, T, FnAttrsFromDeclSpec); diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp new file mode 100644 index 000000000000..cd71d55fc5ce --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// XFAIL: * + +struct notlit { + notlit() {} +}; +struct notlit2 { + notlit2() {} +}; + +// valid declarations +constexpr int i1 = 0; +constexpr int f1() { return 0; } +struct s1 { + constexpr static int mi = 0; +}; + +// invalid declarations +// not a definition of an object +constexpr extern int i2; // x +// not a literal type +constexpr notlit nl1; // x +// function parameters +void f2(constexpr int i) {} // x +// non-static member +struct s2 { + constexpr int mi; // x +}; +// redeclaration mismatch +constexpr int f3(); // n +int f3(); // x +int f4(); // n +constexpr int f4(); // x + +// template stuff +template +constexpr T ft(T t) { return t; } + +// specialization can differ in constepxr +template <> +notlit ft(notlit nl) { return nl; } + +constexpr int i3 = ft(1); + +void test() { + // ignore constexpr when instantiating with non-literal + notlit2 nl2; + (void)ft(nl2); +} + +// Examples from the standard: +constexpr int square(int x); +constexpr int bufsz = 1024; + +constexpr struct pixel { // x + int x; + int y; + constexpr pixel(int); +}; + +constexpr pixel::pixel(int a) + : x(square(a)), y(square(a)) + { } + +constexpr pixel small(2); // x (no definition of square(int) yet, so can't + // constexpr-eval pixel(int)) + +constexpr int square(int x) { + return x * x; +} + +constexpr pixel large(4); // now valid + +int next(constexpr int x) { // x + return x + 1; +} + +extern constexpr int memsz; // x