From patchwork Wed Oct 27 21:48:30 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 69416 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 262ACB70D5 for ; Thu, 28 Oct 2010 08:48:49 +1100 (EST) Received: (qmail 10983 invoked by alias); 27 Oct 2010 21:48:45 -0000 Received: (qmail 10678 invoked by uid 22791); 27 Oct 2010 21:48:43 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_CX, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 27 Oct 2010 21:48:33 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o9RLmVIf001678 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 27 Oct 2010 17:48:31 -0400 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id o9RLmUqE011019 for ; Wed, 27 Oct 2010 17:48:31 -0400 Message-ID: <4CC89E2E.7080702@redhat.com> Date: Wed, 27 Oct 2010 17:48:30 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.14) Gecko/20101020 Lightning/1.0b1 Shredder/3.0.10pre MIME-Version: 1.0 To: gcc-patches List Subject: C++0x constexpr PATCH #4: is_literal_type Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch adds is_literal_type to the header. Tested x86_64-pc-linux-gnu, applied to trunk. More patches will follow in the next few days; if you want to play with constexpr before then, you can grab the constexpr branch from git. commit bc25eceef8f718c792a25efbb8b6d1ecd6f7f131 Author: Jason Merrill Date: Tue Oct 26 14:49:50 2010 -0400 gcc/c-family/ * c-common.c (c_common_reswords): Add __is_literal_type. * c-common.h (enum rid): Add RID_IS_LITERAL_TYPE. gcc/cp/ * cp-tree.h (cp_trait_kind): Add CPTK_IS_LITERAL_TYPE. * cxx-pretty-print.c (pp_cxx_trait_expression): Handle it. * semantics.c (trait_expr_value, finish_trait_expr): Likewise. * parser.c (cp_parser_primary_expression): Handle RID_IS_LITERAL_TYPE. (cp_parser_trait_expr): Likewise. libstdc++-v3/ * include/std/type_traits (is_literal_type): New. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 98568e8..3cdc663 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -439,6 +439,7 @@ const struct c_common_resword c_common_reswords[] = { "__is_standard_layout", RID_IS_STD_LAYOUT, D_CXXONLY }, { "__is_trivial", RID_IS_TRIVIAL, D_CXXONLY }, { "__is_union", RID_IS_UNION, D_CXXONLY }, + { "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY }, { "__imag", RID_IMAGPART, 0 }, { "__imag__", RID_IMAGPART, 0 }, { "__inline", RID_INLINE, 0 }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index aa877d4..f2c6958 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -140,7 +140,7 @@ enum rid RID_IS_EMPTY, RID_IS_ENUM, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_STD_LAYOUT, RID_IS_TRIVIAL, - RID_IS_UNION, + RID_IS_UNION, RID_IS_LITERAL_TYPE, /* C++0x */ RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1cd776a..7595b6f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -567,6 +567,7 @@ typedef enum cp_trait_kind CPTK_IS_POLYMORPHIC, CPTK_IS_STD_LAYOUT, CPTK_IS_TRIVIAL, + CPTK_IS_LITERAL_TYPE, CPTK_IS_UNION } cp_trait_kind; diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index bbef227..09fcc49 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -2369,6 +2369,9 @@ pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t) case CPTK_IS_UNION: pp_cxx_ws_string (pp, "__is_union"); break; + case CPTK_IS_LITERAL_TYPE: + pp_cxx_ws_string (pp, "__is_literal_type"); + break; default: gcc_unreachable (); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0d28345..360e197 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3814,6 +3814,7 @@ cp_parser_primary_expression (cp_parser *parser, case RID_IS_STD_LAYOUT: case RID_IS_TRIVIAL: case RID_IS_UNION: + case RID_IS_LITERAL_TYPE: return cp_parser_trait_expr (parser, token->keyword); /* Objective-C++ expressions. */ @@ -7365,6 +7366,9 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) case RID_IS_UNION: kind = CPTK_IS_UNION; break; + case RID_IS_LITERAL_TYPE: + kind = CPTK_IS_LITERAL_TYPE; + break; default: gcc_unreachable (); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0ca8c33..5926963 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5104,6 +5104,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_UNION: return (type_code1 == UNION_TYPE); + case CPTK_IS_LITERAL_TYPE: + return (literal_type_p (type1)); + default: gcc_unreachable (); return false; @@ -5152,6 +5155,7 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) || kind == CPTK_IS_POLYMORPHIC || kind == CPTK_IS_STD_LAYOUT || kind == CPTK_IS_TRIVIAL + || kind == CPTK_IS_LITERAL_TYPE || kind == CPTK_IS_UNION); if (kind == CPTK_IS_CONVERTIBLE_TO) @@ -5195,6 +5199,7 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_POLYMORPHIC: case CPTK_IS_STD_LAYOUT: case CPTK_IS_TRIVIAL: + case CPTK_IS_LITERAL_TYPE: if (!check_trait_type (type1)) { error ("incomplete type %qT not allowed", type1); diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-is_literal.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-is_literal.C new file mode 100644 index 0000000..d1b9543 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-is_literal.C @@ -0,0 +1,38 @@ +// { dg-options -std=c++0x } + +#include + +#define IS_LIT(T) (std::is_literal_type::value) +#define SA(X) static_assert (X, #X) +#define YES(T) SA(IS_LIT(T)) +#define NO(T) SA(!IS_LIT(T)) + +enum E1 { }; +enum class E2 { }; +struct Literal {}; + +struct NotLiteral { + ~NotLiteral(); +}; + +YES(int); +YES(int[]); +YES(int[3]); +YES(double); +YES(void *); +YES(decltype (nullptr)); +YES(int Literal::*); +YES(void (Literal::*)()); +YES(E1); +YES(E2); +YES(Literal); +NO (NotLiteral); +YES(NotLiteral *); +YES(NotLiteral NotLiteral::*); +YES(NotLiteral (NotLiteral::*)(NotLiteral)); + +struct A { + A(const A&) = default; +}; + +NO(A); // no constexpr ctor other than copy diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index cde741e..a5a62d6 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -192,6 +192,12 @@ namespace std : public integral_constant { }; + /// is_literal_type + template + struct is_literal_type + : public integral_constant + { }; + template typename add_rvalue_reference<_Tp>::type declval() noexcept; diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc index f0c6546..b18ff2f 100644 --- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // . -// { dg-error "static assertion failed" "" { target *-*-* } 682 } +// { dg-error "static assertion failed" "" { target *-*-* } 688 } #include diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc index 8a09c65..d74f4e63 100644 --- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc @@ -48,5 +48,5 @@ void test01() // { dg-error "instantiated from here" "" { target *-*-* } 40 } // { dg-error "instantiated from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 645 } -// { dg-error "declaration of" "" { target *-*-* } 609 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 651 } +// { dg-error "declaration of" "" { target *-*-* } 615 } diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc index ba68414..18fd4fb 100644 --- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc @@ -48,5 +48,5 @@ void test01() // { dg-error "instantiated from here" "" { target *-*-* } 40 } // { dg-error "instantiated from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 568 } -// { dg-error "declaration of" "" { target *-*-* } 532 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 574 } +// { dg-error "declaration of" "" { target *-*-* } 538 }