diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/constraint.cc | 3 | ||||
-rw-r--r-- | gcc/cp/cp-trait.def | 1 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/parser.cc | 41 | ||||
-rw-r--r-- | gcc/cp/semantics.cc | 4 | ||||
-rw-r--r-- | gcc/cp/tree.cc | 36 |
6 files changed, 78 insertions, 8 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 309ebc8..925dc67 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3170,6 +3170,9 @@ diagnose_trait_expr (location_t loc, tree expr, tree args) case CPTK_IS_FUNCTION: inform (loc, "%qT is not a function", t1); break; + case CPTK_IS_IMPLICIT_LIFETIME: + inform (decl_loc, "%qT is not an implicit-lifetime type", t1); + break; case CPTK_IS_INVOCABLE: { if (!TREE_VEC_LENGTH (t2)) diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 5e4493a..c820184 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -76,6 +76,7 @@ DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1) DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1) DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1) DEFTRAIT_EXPR (IS_FUNCTION, "__is_function", 1) +DEFTRAIT_EXPR (IS_IMPLICIT_LIFETIME, "__builtin_is_implicit_lifetime", 1) DEFTRAIT_EXPR (IS_INVOCABLE, "__is_invocable", -1) DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2) DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fcba9f5..8c211ab 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8376,6 +8376,7 @@ extern bool std_layout_type_p (const_tree); extern bool trivial_type_p (const_tree); extern bool trivially_relocatable_type_p (tree); extern bool replaceable_type_p (tree); +extern bool implicit_lifetime_type_p (tree); extern bool trivially_copyable_p (const_tree); extern bool type_has_unique_obj_representations (const_tree); extern bool scalarish_type_p (const_tree); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9280632..0917a16 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -51233,6 +51233,7 @@ cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok, directive[1], directive[2]); if (dir + && dir->id != PRAGMA_OMP_END && (dir->kind == C_OMP_DIR_DECLARATIVE || dir->kind == C_OMP_DIR_INFORMATIONAL || dir->kind == C_OMP_DIR_META)) @@ -51241,9 +51242,9 @@ cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok, "informational, and meta directives " "not permitted", p); else if (dir == NULL - || dir->id == PRAGMA_OMP_END - || (!dir->second && directive[1]) - || (!dir->third && directive[2])) + || dir->id == PRAGMA_OMP_END + || (!dir->second && directive[1]) + || (!dir->third && directive[2])) error_at (dloc, "unknown OpenMP directive name in " "%qs clause argument", p); else @@ -52739,6 +52740,18 @@ cp_parser_omp_metadirective (cp_parser *parser, cp_token *pragma_tok, } cp_parser_skip_to_pragma_eol (parser, pragma_tok); + /* If only one selector matches and it evaluates to 'omp nothing', no need to + proceed. */ + if (ctxs.length () == 1) + { + tree ctx = ctxs[0]; + if (ctx == NULL_TREE + || (omp_context_selector_matches (ctx, NULL_TREE, false) == 1 + && cp_parser_pragma_kind (&directive_tokens[0]) + == PRAGMA_OMP_NOTHING)) + return; + } + if (!default_seen) { /* Add a default clause that evaluates to 'omp nothing'. */ @@ -53851,6 +53864,14 @@ cp_parser_omp_error (cp_parser *parser, cp_token *pragma_tok, "may only be used in compound statements"); return true; } + if (parser->omp_for_parse_state + && parser->omp_for_parse_state->in_intervening_code) + { + error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause " + "may not be used in intervening code"); + parser->omp_for_parse_state->fail = true; + return true; + } tree fndecl = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR : BUILT_IN_GOMP_WARNING); @@ -54768,11 +54789,15 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p) id = cp_parser_pragma_kind (pragma_tok); if (parser->omp_for_parse_state && parser->omp_for_parse_state->in_intervening_code - && id >= PRAGMA_OMP__START_ - && id <= PRAGMA_OMP__LAST_) - { - error_at (pragma_tok->location, - "intervening code must not contain OpenMP directives"); + && id >= PRAGMA_OMP__START_ && id <= PRAGMA_OMP__LAST_ + /* Allow a safe subset of non-executable directives. See classification in + array c_omp_directives. */ + && id != PRAGMA_OMP_METADIRECTIVE && id != PRAGMA_OMP_NOTHING + && id != PRAGMA_OMP_ASSUME && id != PRAGMA_OMP_ERROR) + { + error_at ( + pragma_tok->location, + "intervening code must not contain executable OpenMP directives"); parser->omp_for_parse_state->fail = true; cp_parser_skip_to_pragma_eol (parser, pragma_tok); return false; diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index c818b73..ad12155 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -13595,6 +13595,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_FUNCTION: return type_code1 == FUNCTION_TYPE; + case CPTK_IS_IMPLICIT_LIFETIME: + return implicit_lifetime_type_p (type1); + case CPTK_IS_INVOCABLE: return !error_operand_p (build_invoke (type1, type2, tf_none)); @@ -13914,6 +13917,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) type to know whether an array is an aggregate, so use kind=4 here. */ case CPTK_IS_AGGREGATE: case CPTK_IS_FINAL: + case CPTK_IS_IMPLICIT_LIFETIME: if (!check_trait_type (type1, /* kind = */ 4)) return error_mark_node; break; diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 814465c..3edb74a 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -5097,6 +5097,42 @@ replaceable_type_p (tree t) return true; } +/* Returns 1 iff type T is an implicit-lifetime type, as defined in + [basic.types.general] and [class.prop]. */ + +bool +implicit_lifetime_type_p (tree t) +{ + if (SCALAR_TYPE_P (t) + || (TREE_CODE (t) == ARRAY_TYPE + && !(TYPE_SIZE (t) && integer_zerop (TYPE_SIZE (t)))) + /* GNU extension. */ + || TREE_CODE (t) == VECTOR_TYPE) + return true; + if (!CLASS_TYPE_P (t)) + return false; + t = TYPE_MAIN_VARIANT (t); + if (CP_AGGREGATE_TYPE_P (t) + && (!CLASSTYPE_DESTRUCTOR (t) + || !user_provided_p (CLASSTYPE_DESTRUCTOR (t)))) + return true; + if (is_trivially_xible (BIT_NOT_EXPR, t, NULL_TREE)) + { + if (is_trivially_xible (INIT_EXPR, t, make_tree_vec (0))) + return true; + tree arg = make_tree_vec (1); + tree ct + = cp_build_qualified_type (t, (cp_type_quals (t) | TYPE_QUAL_CONST)); + TREE_VEC_ELT (arg, 0) = cp_build_reference_type (ct, /*rval=*/false); + if (is_trivially_xible (INIT_EXPR, t, arg)) + return true; + TREE_VEC_ELT (arg, 0) = t; + if (is_trivially_xible (INIT_EXPR, t, arg)) + return true; + } + return false; +} + /* Returns 1 iff type T is a POD type, as defined in [basic.types]. */ bool |