commit d3b4453834bb2e3cc1c875e76fe593c16f263f77 Author: Jason Merrill Date: Fri Feb 16 16:53:47 2018 -0500 PR c++/83911 - ICE with multiversioned constructor. gcc/ * attribs.c (make_dispatcher_decl): Copy METHOD_TYPE, DECL_CXX_{CON,DE}STRUCTOR_P. gcc/cp/ * cp-tree.h (DECL_CONSTRUCTOR_P): Use DECL_CXX_CONSTRUCTOR_P. (DECL_DESTRUCTOR_P): Use DECL_CXX_DESTRUCTOR_P. * mangle.c (write_unqualified_name): Check IDENTIFIER_[CD]TOR_P. diff --git a/gcc/attribs.c b/gcc/attribs.c index bfadf124dcb..2e9e69904f0 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -1063,9 +1063,14 @@ make_dispatcher_decl (const tree decl) func_name = xstrdup (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); fn_type = TREE_TYPE (decl); - func_type = build_function_type (TREE_TYPE (fn_type), - TYPE_ARG_TYPES (fn_type)); - + if (TREE_CODE (fn_type) == METHOD_TYPE) + func_type = build_method_type_directly (TYPE_METHOD_BASETYPE (fn_type), + TREE_TYPE (fn_type), + TYPE_ARG_TYPES (fn_type)); + else + func_type = build_function_type (TREE_TYPE (fn_type), + TYPE_ARG_TYPES (fn_type)); + func_decl = build_fn_decl (func_name, func_type); XDELETEVEC (func_name); TREE_USED (func_decl) = 1; @@ -1078,6 +1083,9 @@ make_dispatcher_decl (const tree decl) /* This will be of type IFUNCs have to be externally visible. */ TREE_PUBLIC (func_decl) = 1; + DECL_CXX_CONSTRUCTOR_P (func_decl) = DECL_CXX_CONSTRUCTOR_P (decl); + DECL_CXX_DESTRUCTOR_P (func_decl) = DECL_CXX_DESTRUCTOR_P (decl); + return func_decl; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 17d8c6d2650..268be0fd543 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2695,7 +2695,7 @@ struct GTY(()) lang_decl { /* For FUNCTION_DECLs and TEMPLATE_DECLs: nonzero means that this function is a constructor. */ #define DECL_CONSTRUCTOR_P(NODE) \ - IDENTIFIER_CTOR_P (DECL_NAME (NODE)) + DECL_CXX_CONSTRUCTOR_P (STRIP_TEMPLATE (NODE)) /* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a complete object. */ @@ -2724,7 +2724,7 @@ struct GTY(()) lang_decl { /* Nonzero if NODE (a FUNCTION_DECL or TEMPLATE_DECL) is a destructor. */ #define DECL_DESTRUCTOR_P(NODE) \ - IDENTIFIER_DTOR_P (DECL_NAME (NODE)) + DECL_CXX_DESTRUCTOR_P (STRIP_TEMPLATE (NODE)) /* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the specialized in-charge constructor, in-charge deleting constructor, diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 94c4bed2848..ecd4eb066d4 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -1351,9 +1351,9 @@ write_unqualified_name (tree decl) else if (DECL_DECLARES_FUNCTION_P (decl)) { found = true; - if (DECL_CONSTRUCTOR_P (decl)) + if (IDENTIFIER_CTOR_P (DECL_NAME (decl))) write_special_name_constructor (decl); - else if (DECL_DESTRUCTOR_P (decl)) + else if (IDENTIFIER_DTOR_P (DECL_NAME (decl))) write_special_name_destructor (decl); else if (DECL_CONV_FN_P (decl)) { diff --git a/gcc/testsuite/g++.dg/ext/mv27.C b/gcc/testsuite/g++.dg/ext/mv27.C new file mode 100644 index 00000000000..443a54be765 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/mv27.C @@ -0,0 +1,18 @@ +// PR c++/83911 +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-require-ifunc "" } + +class SimdFloat +{ +public: + __attribute__ ((target ("default"))) + SimdFloat(float x) {} + + __attribute__ ((target ("avx2"))) + SimdFloat(float x) {} +}; + +SimdFloat foo() +{ + return 1; +}