From: Nathan Sidwell Date: Fri, 30 Jun 2017 13:11:01 +0000 (+0000) Subject: call.c (build_new_method_call_1): Use constructo_name to get ctor name. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3b5c768c40c78618962f2d6e86c9c7affdf86eb8;p=gcc.git call.c (build_new_method_call_1): Use constructo_name to get ctor name. * call.c (build_new_method_call_1): Use constructo_name to get ctor name. Move argument processing earlier to merge cdtor handling blocks. * decl.c (grokfndecl): Cdtors have special names. * method.c (implicitly_declare_fn): Likewise. Simplify flag setting. * pt.c (check_explicit_specialization): Cdtor name is already special. * search.c (class_method_index_for_fn): Likewise. * g++.dg/plugin/decl-plugin-test.C: Expect special ctor name. From-SVN: r249838 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 38b63e43403..c54cb2407e4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2017-06-30 Nathan Sidwell + * call.c (build_new_method_call_1): Use constructo_name to get + ctor name. Move argument processing earlier to merge cdtor + handling blocks. + * decl.c (grokfndecl): Cdtors have special names. + * method.c (implicitly_declare_fn): Likewise. Simplify flag setting. + * pt.c (check_explicit_specialization): Cdtor name is already + special. + * search.c (class_method_index_for_fn): Likewise. + PR c++/81229 * name-lookup.c (do_pushdecl): Reset IDENTIFIER_TYPE when finding a matching TYPE_DECL. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 06758203b89..fac6b6c16ac 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8994,6 +8994,7 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, if (! (complain & tf_error)) return error_mark_node; + name = constructor_name (basetype); if (permerror (input_location, "cannot call constructor %<%T::%D%> directly", basetype, name)) @@ -9004,6 +9005,19 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, return call; } + /* Process the argument list. */ + if (args != NULL && *args != NULL) + { + *args = resolve_args (*args, complain); + if (*args == NULL) + return error_mark_node; + } + + /* Consider the object argument to be used even if we end up selecting a + static member function. */ + instance = mark_type_use (instance); + + /* Figure out whether to skip the first argument for the error message we will display to users if an error occurs. We don't want to display any compiler-generated arguments. The "this" @@ -9013,35 +9027,18 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, skip_first_for_error = false; if (IDENTIFIER_CDTOR_P (name)) { - /* Callers should explicitly indicate whether they want to construct + /* Callers should explicitly indicate whether they want to ctor the complete object or just the part without virtual bases. */ gcc_assert (name != ctor_identifier); - /* Similarly for destructors. */ - gcc_assert (name != dtor_identifier); + /* Remove the VTT pointer, if present. */ if ((name == base_ctor_identifier || name == base_dtor_identifier) && CLASSTYPE_VBASECLASSES (basetype)) skip_first_for_error = true; - } - /* Process the argument list. */ - if (args != NULL && *args != NULL) - { - *args = resolve_args (*args, complain); - if (*args == NULL) - return error_mark_node; - } - - /* Consider the object argument to be used even if we end up selecting a - static member function. */ - instance = mark_type_use (instance); - - /* It's OK to call destructors and constructors on cv-qualified objects. - Therefore, convert the INSTANCE to the unqualified type, if - necessary. */ - if (DECL_DESTRUCTOR_P (fn) - || DECL_CONSTRUCTOR_P (fn)) - { + /* It's OK to call destructors and constructors on cv-qualified + objects. Therefore, convert the INSTANCE to the unqualified + type, if necessary. */ if (!same_type_p (basetype, TREE_TYPE (instance))) { instance = build_this (instance); @@ -9049,8 +9046,8 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, instance = build_fold_indirect_ref (instance); } } - if (DECL_DESTRUCTOR_P (fn)) - name = complete_dtor_identifier; + else + gcc_assert (!DECL_DESTRUCTOR_P (fn) && !DECL_CONSTRUCTOR_P (fn)); /* For the overload resolution we need to find the actual `this` that would be captured if the call turns out to be to a diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 50260756727..abb6cc4fabf 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8518,9 +8518,11 @@ grokfndecl (tree ctype, case sfk_copy_constructor: case sfk_move_constructor: DECL_CONSTRUCTOR_P (decl) = 1; + DECL_NAME (decl) = ctor_identifier; break; case sfk_destructor: DECL_DESTRUCTOR_P (decl) = 1; + DECL_NAME (decl) = dtor_identifier; break; default: break; diff --git a/gcc/cp/method.c b/gcc/cp/method.c index ba65284a066..0646b08e577 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1968,12 +1968,12 @@ implicitly_declare_fn (special_function_kind kind, tree type, { case sfk_destructor: /* Destructor. */ - name = constructor_name (type); + name = dtor_identifier; break; case sfk_constructor: /* Default constructor. */ - name = constructor_name (type); + name = ctor_identifier; break; case sfk_copy_constructor: @@ -1989,7 +1989,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, name = cp_assignment_operator_id (NOP_EXPR); } else - name = constructor_name (type); + name = ctor_identifier; if (kind == sfk_inheriting_constructor) parameter_types = inherited_parms; @@ -2053,13 +2053,14 @@ implicitly_declare_fn (special_function_kind kind, tree type, fn = build_lang_decl (FUNCTION_DECL, name, fn_type); if (kind != sfk_inheriting_constructor) DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type)); - if (kind == sfk_constructor || kind == sfk_copy_constructor - || kind == sfk_move_constructor || kind == sfk_inheriting_constructor) - DECL_CONSTRUCTOR_P (fn) = 1; - else if (kind == sfk_destructor) - DECL_DESTRUCTOR_P (fn) = 1; - else + + if (!IDENTIFIER_CDTOR_P (name)) + /* Assignment operator. */ SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR); + else if (IDENTIFIER_CTOR_P (name)) + DECL_CONSTRUCTOR_P (fn) = true; + else + DECL_DESTRUCTOR_P (fn) = true; SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3ecacbd62de..79b55b59376 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2881,9 +2881,8 @@ check_explicit_specialization (tree declarator, if (constructor_name_p (name, ctype)) { - int is_constructor = DECL_CONSTRUCTOR_P (decl); - - if (is_constructor ? !TYPE_HAS_USER_CONSTRUCTOR (ctype) + if (DECL_CONSTRUCTOR_P (decl) + ? !TYPE_HAS_USER_CONSTRUCTOR (ctype) : !CLASSTYPE_DESTRUCTOR (ctype)) { /* From [temp.expl.spec]: @@ -2898,7 +2897,7 @@ check_explicit_specialization (tree declarator, return error_mark_node; } - name = is_constructor ? ctor_identifier : dtor_identifier; + name = DECL_NAME (decl); } if (!DECL_CONV_FN_P (decl)) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 7bcbcbfe535..9d8a629118f 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1713,10 +1713,7 @@ class_method_index_for_fn (tree class_type, tree function) { gcc_assert (DECL_DECLARES_FUNCTION_P (function)); - return lookup_fnfields_1 (class_type, - DECL_CONSTRUCTOR_P (function) ? ctor_identifier : - DECL_DESTRUCTOR_P (function) ? dtor_identifier : - DECL_NAME (function)); + return lookup_fnfields_1 (class_type, DECL_NAME (function)); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8a6311a6565..30c087edb09 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2017-06-30 Nathan Sidwell + * g++.dg/plugin/decl-plugin-test.C: Expect special ctor name. + PR c++/81229 * g++.dg/lookup/pr81229.C: New. diff --git a/gcc/testsuite/g++.dg/plugin/decl-plugin-test.C b/gcc/testsuite/g++.dg/plugin/decl-plugin-test.C index 08a2ff2aa5d..e6bd746892c 100644 --- a/gcc/testsuite/g++.dg/plugin/decl-plugin-test.C +++ b/gcc/testsuite/g++.dg/plugin/decl-plugin-test.C @@ -17,7 +17,7 @@ class test_class { int class_field1; // { dg-warning "Decl Field class_field1" } int class_field2; // { dg-warning "Decl Field class_field2" } - test_class() // { dg-warning "Decl Function test_class" } + test_class() // { dg-warning "Decl Function __ct" } : class_field1(0), class_field2(0) {}