From adecb3f41f0bb582c936e2be5fda659a611067ca Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 21 May 1999 15:55:56 +0000 Subject: [PATCH] Make-lang.in (cc1plus): Make it depend on gxx.gperf. * Make-lang.in (cc1plus): Make it depend on gxx.gperf. * cp-tree.h: Fix typo in documentation on pointers-to-members. (cp_build_qualified_type): Make it a macro. (cp_build_qualified_type_real): Declare. * decl.c (grokdeclarator): Remove misleading comment. Avoid problem with template parameters and restrict-qualification. * gxx.gperf: Replace NORID with RID_UNUSED throughout. * hash.h: Regenerated. * lex.h (rid): Move RID_FIRST_MODIFIER and RID_LAST_MODIFIER into the enumeration. (NORID): Remove definition. * pt.c (tsubst_aggr_type): Use cp_build_qualified_type_real. (tsubst): Likewise. Remove special handling for FUNCTION_TYPEs. (fn_type_unification): Check that the function type resulting from the deduction is legal. (check_cv_quals_for_unify): Don't handle FUNCTION_TYPEs specially. (unify): Use cp_build_qualified_type_real. * tree.c (build_cplus_array_type_1): Handle error_marks as inputs. (cp_build_qualified_type): Rename to ... (cp_build_qualified_type_real): Add additional COMPLAIN parameter and modify appropriately. Co-Authored-By: Nathan Sidwell From-SVN: r27086 --- gcc/cp/ChangeLog | 25 ++++++++- gcc/cp/Make-lang.in | 2 +- gcc/cp/cp-tree.h | 6 ++- gcc/cp/decl.c | 8 +-- gcc/cp/gxx.gperf | 120 ++++++++++++++++++++++---------------------- gcc/cp/hash.h | 120 ++++++++++++++++++++++---------------------- gcc/cp/lex.h | 9 ++-- gcc/cp/pt.c | 71 +++++++++++++++----------- gcc/cp/tree.c | 35 ++++++++++--- 9 files changed, 225 insertions(+), 171 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6ff46de2a62..6c64408f1db 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,28 @@ 1999-05-21 Mark Mitchell - + Nathan Sidwell + + * Make-lang.in (cc1plus): Make it depend on gxx.gperf. + * cp-tree.h: Fix typo in documentation on pointers-to-members. + (cp_build_qualified_type): Make it a macro. + (cp_build_qualified_type_real): Declare. + * decl.c (grokdeclarator): Remove misleading comment. Avoid + problem with template parameters and restrict-qualification. + * gxx.gperf: Replace NORID with RID_UNUSED throughout. + * hash.h: Regenerated. + * lex.h (rid): Move RID_FIRST_MODIFIER and RID_LAST_MODIFIER into + the enumeration. + (NORID): Remove definition. + * pt.c (tsubst_aggr_type): Use cp_build_qualified_type_real. + (tsubst): Likewise. Remove special handling for FUNCTION_TYPEs. + (fn_type_unification): Check that the function type resulting from + the deduction is legal. + (check_cv_quals_for_unify): Don't handle FUNCTION_TYPEs specially. + (unify): Use cp_build_qualified_type_real. + * tree.c (build_cplus_array_type_1): Handle error_marks as inputs. + (cp_build_qualified_type): Rename to ... + (cp_build_qualified_type_real): Add additional COMPLAIN parameter + and modify appropriately. + * typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to reveal optimization opportunities. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index d5d4e4d4cef..72795da3499 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -120,7 +120,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \ $(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o \ - $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def hash.o + $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def $(srcdir)/cp/gxx.gperf hash.o cd cp; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus$(exeext) # # Build hooks: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c2becd903af..b2b6313fd85 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1721,7 +1721,7 @@ extern int flag_new_for_scope; non-virtual function. Of course, `&f__2B2' is the name of that function. - (Of course, the exactl values may differ depending on the mangling + (Of course, the exact values may differ depending on the mangling scheme, sizes of types, and such.). */ /* Get the POINTER_TYPE to the METHOD_TYPE associated with this @@ -2100,7 +2100,6 @@ extern void check_function_format PROTO((tree, tree, tree)); /* Print an error message for invalid operands to arith operation CODE. NOP_EXPR is used as a special case (see truthvalue_conversion). */ extern void binary_op_error PROTO((enum tree_code)); -extern tree cp_build_qualified_type PROTO((tree, int)); extern tree canonical_type_variant PROTO((tree)); extern void c_expand_expr_stmt PROTO((tree)); /* Validate the expression after `case' and apply default promotions. */ @@ -3387,6 +3386,9 @@ extern int is_dummy_object PROTO((tree)); extern tree search_tree PROTO((tree, tree (*)(tree))); extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree)); extern tree make_ptrmem_cst PROTO((tree, tree)); +extern tree cp_build_qualified_type_real PROTO((tree, int, int)); +#define cp_build_qualified_type(TYPE, QUALS) \ + cp_build_qualified_type_real ((TYPE), (QUALS), /*complain=*/1) #define scratchalloc expralloc #define scratch_tree_cons expr_tree_cons diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 111ce222fe9..dd2dbb754b0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11650,9 +11650,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) if (RIDBIT_SETP (RID_STATIC, specbits)) DECL_THIS_STATIC (decl) = 1; - /* Record constancy and volatility. */ - /* FIXME: Disallow `restrict' pointer-to-member declarations. */ - c_apply_type_quals_to_decl (type_quals, decl); + /* Record constancy and volatility. There's no need to do this + when processing a template; we'll do this for the instantiated + declaration based on the type of DECL. */ + if (!processing_template_decl) + c_apply_type_quals_to_decl (type_quals, decl); return decl; } diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf index 1e621c4a22d..2134939fed7 100644 --- a/gcc/cp/gxx.gperf +++ b/gcc/cp/gxx.gperf @@ -3,109 +3,109 @@ %} struct resword { const char *name; short token; enum rid rid;}; %% -__alignof, ALIGNOF, NORID -__alignof__, ALIGNOF, NORID -__asm, ASM_KEYWORD, NORID -__asm__, ASM_KEYWORD, NORID -__attribute, ATTRIBUTE, NORID -__attribute__, ATTRIBUTE, NORID +__alignof, ALIGNOF, RID_UNUSED +__alignof__, ALIGNOF, RID_UNUSED +__asm, ASM_KEYWORD, RID_UNUSED +__asm__, ASM_KEYWORD, RID_UNUSED +__attribute, ATTRIBUTE, RID_UNUSED +__attribute__, ATTRIBUTE, RID_UNUSED __complex, TYPESPEC, RID_COMPLEX __complex__, TYPESPEC, RID_COMPLEX __const, CV_QUALIFIER, RID_CONST __const__, CV_QUALIFIER, RID_CONST -__extension__, EXTENSION, NORID -__imag, IMAGPART, NORID -__imag__, IMAGPART, NORID +__extension__, EXTENSION, RID_UNUSED +__imag, IMAGPART, RID_UNUSED +__imag__, IMAGPART, RID_UNUSED __inline, SCSPEC, RID_INLINE __inline__, SCSPEC, RID_INLINE -__label__, LABEL, NORID +__label__, LABEL, RID_UNUSED __null, CONSTANT, RID_NULL -__real, REALPART, NORID -__real__, REALPART, NORID +__real, REALPART, RID_UNUSED +__real__, REALPART, RID_UNUSED __restrict, CV_QUALIFIER, RID_RESTRICT __restrict__, CV_QUALIFIER, RID_RESTRICT __signature__, AGGR, RID_SIGNATURE /* Extension */, __signed, TYPESPEC, RID_SIGNED __signed__, TYPESPEC, RID_SIGNED -__sigof__, SIGOF, NORID /* Extension */, -__typeof, TYPEOF, NORID -__typeof__, TYPEOF, NORID +__sigof__, SIGOF, RID_UNUSED /* Extension */, +__typeof, TYPEOF, RID_UNUSED +__typeof__, TYPEOF, RID_UNUSED __volatile, CV_QUALIFIER, RID_VOLATILE __volatile__, CV_QUALIFIER, RID_VOLATILE __wchar_t, TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */, -asm, ASM_KEYWORD, NORID, -and, ANDAND, NORID, -and_eq, ASSIGN, NORID, +asm, ASM_KEYWORD, RID_UNUSED, +and, ANDAND, RID_UNUSED, +and_eq, ASSIGN, RID_UNUSED, auto, SCSPEC, RID_AUTO, -bitand, '&', NORID, -bitor, '|', NORID, +bitand, '&', RID_UNUSED, +bitor, '|', RID_UNUSED, bool, TYPESPEC, RID_BOOL, -break, BREAK, NORID, -case, CASE, NORID, -catch, CATCH, NORID, +break, BREAK, RID_UNUSED, +case, CASE, RID_UNUSED, +catch, CATCH, RID_UNUSED, char, TYPESPEC, RID_CHAR, class, AGGR, RID_CLASS, -compl, '~', NORID, +compl, '~', RID_UNUSED, const, CV_QUALIFIER, RID_CONST, -const_cast, CONST_CAST, NORID, -continue, CONTINUE, NORID, -default, DEFAULT, NORID, -delete, DELETE, NORID, -do, DO, NORID, +const_cast, CONST_CAST, RID_UNUSED, +continue, CONTINUE, RID_UNUSED, +default, DEFAULT, RID_UNUSED, +delete, DELETE, RID_UNUSED, +do, DO, RID_UNUSED, double, TYPESPEC, RID_DOUBLE, -dynamic_cast, DYNAMIC_CAST, NORID, -else, ELSE, NORID, -enum, ENUM, NORID, +dynamic_cast, DYNAMIC_CAST, RID_UNUSED, +else, ELSE, RID_UNUSED, +enum, ENUM, RID_UNUSED, explicit, SCSPEC, RID_EXPLICIT, export, SCSPEC, RID_EXPORT, extern, SCSPEC, RID_EXTERN, -false, CXX_FALSE, NORID, +false, CXX_FALSE, RID_UNUSED, float, TYPESPEC, RID_FLOAT, -for, FOR, NORID, +for, FOR, RID_UNUSED, friend, SCSPEC, RID_FRIEND, -goto, GOTO, NORID, -if, IF, NORID, +goto, GOTO, RID_UNUSED, +if, IF, RID_UNUSED, inline, SCSPEC, RID_INLINE, int, TYPESPEC, RID_INT, long, TYPESPEC, RID_LONG, mutable, SCSPEC, RID_MUTABLE, -namespace, NAMESPACE, NORID, -new, NEW, NORID, -not, '!', NORID, -not_eq, EQCOMPARE, NORID, -operator, OPERATOR, NORID, -or, OROR, NORID, -or_eq, ASSIGN, NORID, +namespace, NAMESPACE, RID_UNUSED, +new, NEW, RID_UNUSED, +not, '!', RID_UNUSED, +not_eq, EQCOMPARE, RID_UNUSED, +operator, OPERATOR, RID_UNUSED, +or, OROR, RID_UNUSED, +or_eq, ASSIGN, RID_UNUSED, private, VISSPEC, RID_PRIVATE, protected, VISSPEC, RID_PROTECTED, public, VISSPEC, RID_PUBLIC, register, SCSPEC, RID_REGISTER, -reinterpret_cast, REINTERPRET_CAST, NORID, -return, RETURN_KEYWORD, NORID, +reinterpret_cast, REINTERPRET_CAST, RID_UNUSED, +return, RETURN_KEYWORD, RID_UNUSED, short, TYPESPEC, RID_SHORT, signature, AGGR, RID_SIGNATURE /* Extension */, signed, TYPESPEC, RID_SIGNED, -sigof, SIGOF, NORID /* Extension */, -sizeof, SIZEOF, NORID, +sigof, SIGOF, RID_UNUSED /* Extension */, +sizeof, SIZEOF, RID_UNUSED, static, SCSPEC, RID_STATIC, -static_cast, STATIC_CAST, NORID, +static_cast, STATIC_CAST, RID_UNUSED, struct, AGGR, RID_RECORD, -switch, SWITCH, NORID, +switch, SWITCH, RID_UNUSED, template, TEMPLATE, RID_TEMPLATE, -this, THIS, NORID, -throw, THROW, NORID, -true, CXX_TRUE, NORID, -try, TRY, NORID, +this, THIS, RID_UNUSED, +throw, THROW, RID_UNUSED, +true, CXX_TRUE, RID_UNUSED, +try, TRY, RID_UNUSED, typedef, SCSPEC, RID_TYPEDEF, -typename, TYPENAME_KEYWORD, NORID, -typeid, TYPEID, NORID, -typeof, TYPEOF, NORID, +typename, TYPENAME_KEYWORD, RID_UNUSED, +typeid, TYPEID, RID_UNUSED, +typeof, TYPEOF, RID_UNUSED, union, AGGR, RID_UNION, unsigned, TYPESPEC, RID_UNSIGNED, -using, USING, NORID, +using, USING, RID_UNUSED, virtual, SCSPEC, RID_VIRTUAL, void, TYPESPEC, RID_VOID, volatile, CV_QUALIFIER, RID_VOLATILE, -while, WHILE, NORID, -xor, '^', NORID, -xor_eq, ASSIGN, NORID, +while, WHILE, RID_UNUSED, +xor, '^', RID_UNUSED, +xor_eq, ASSIGN, RID_UNUSED, diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h index 3c6199630c1..b7db192440c 100644 --- a/gcc/cp/hash.h +++ b/gcc/cp/hash.h @@ -78,16 +78,16 @@ is_reserved_word (str, len) static struct resword wordlist[] = { {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"else", ELSE, NORID,}, + {"else", ELSE, RID_UNUSED,}, {"", 0, 0}, - {"delete", DELETE, NORID,}, - {"case", CASE, NORID,}, - {"__real__", REALPART, NORID}, + {"delete", DELETE, RID_UNUSED,}, + {"case", CASE, RID_UNUSED,}, + {"__real__", REALPART, RID_UNUSED}, {"", 0, 0}, - {"true", CXX_TRUE, NORID,}, - {"catch", CATCH, NORID,}, - {"typeid", TYPEID, NORID,}, - {"try", TRY, NORID,}, + {"true", CXX_TRUE, RID_UNUSED,}, + {"catch", CATCH, RID_UNUSED,}, + {"typeid", TYPEID, RID_UNUSED,}, + {"try", TRY, RID_UNUSED,}, {"", 0, 0}, {"", 0, 0}, {"void", TYPESPEC, RID_VOID,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, @@ -96,23 +96,23 @@ is_reserved_word (str, len) {"protected", VISSPEC, RID_PROTECTED,}, {"extern", SCSPEC, RID_EXTERN,}, {"", 0, 0}, {"", 0, 0}, - {"not", '!', NORID,}, + {"not", '!', RID_UNUSED,}, {"", 0, 0}, {"__signed", TYPESPEC, RID_SIGNED}, {"int", TYPESPEC, RID_INT,}, {"__signed__", TYPESPEC, RID_SIGNED}, - {"__real", REALPART, NORID}, + {"__real", REALPART, RID_UNUSED}, {"", 0, 0}, - {"xor_eq", ASSIGN, NORID,}, + {"xor_eq", ASSIGN, RID_UNUSED,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"__attribute", ATTRIBUTE, NORID}, - {"__asm__", ASM_KEYWORD, NORID}, - {"__attribute__", ATTRIBUTE, NORID}, - {"compl", '~', NORID,}, + {"__attribute", ATTRIBUTE, RID_UNUSED}, + {"__asm__", ASM_KEYWORD, RID_UNUSED}, + {"__attribute__", ATTRIBUTE, RID_UNUSED}, + {"compl", '~', RID_UNUSED,}, {"public", VISSPEC, RID_PUBLIC,}, - {"not_eq", EQCOMPARE, NORID,}, - {"switch", SWITCH, NORID,}, - {"__extension__", EXTENSION, NORID}, + {"not_eq", EQCOMPARE, RID_UNUSED,}, + {"switch", SWITCH, RID_UNUSED,}, + {"__extension__", EXTENSION, RID_UNUSED}, {"const", CV_QUALIFIER, RID_CONST,}, {"static", SCSPEC, RID_STATIC,}, {"", 0, 0}, @@ -121,77 +121,77 @@ is_reserved_word (str, len) {"__inline__", SCSPEC, RID_INLINE}, {"__restrict__", CV_QUALIFIER, RID_RESTRICT}, {"inline", SCSPEC, RID_INLINE,}, - {"const_cast", CONST_CAST, NORID,}, - {"static_cast", STATIC_CAST, NORID,}, + {"const_cast", CONST_CAST, RID_UNUSED,}, + {"static_cast", STATIC_CAST, RID_UNUSED,}, {"__restrict", CV_QUALIFIER, RID_RESTRICT}, - {"xor", '^', NORID,}, + {"xor", '^', RID_UNUSED,}, {"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,}, - {"new", NEW, NORID,}, - {"__alignof__", ALIGNOF, NORID}, + {"new", NEW, RID_UNUSED,}, + {"__alignof__", ALIGNOF, RID_UNUSED}, {"signed", TYPESPEC, RID_SIGNED,}, - {"and", ANDAND, NORID,}, + {"and", ANDAND, RID_UNUSED,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"explicit", SCSPEC, RID_EXPLICIT,}, {"", 0, 0}, - {"__imag__", IMAGPART, NORID}, - {"while", WHILE, NORID,}, + {"__imag__", IMAGPART, RID_UNUSED}, + {"while", WHILE, RID_UNUSED,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"do", DO, NORID,}, - {"typename", TYPENAME_KEYWORD, NORID,}, + {"do", DO, RID_UNUSED,}, + {"typename", TYPENAME_KEYWORD, RID_UNUSED,}, {"friend", SCSPEC, RID_FRIEND,}, - {"continue", CONTINUE, NORID,}, + {"continue", CONTINUE, RID_UNUSED,}, {"class", AGGR, RID_CLASS,}, - {"default", DEFAULT, NORID,}, - {"this", THIS, NORID,}, - {"dynamic_cast", DYNAMIC_CAST, NORID,}, - {"typeof", TYPEOF, NORID,}, + {"default", DEFAULT, RID_UNUSED,}, + {"this", THIS, RID_UNUSED,}, + {"dynamic_cast", DYNAMIC_CAST, RID_UNUSED,}, + {"typeof", TYPEOF, RID_UNUSED,}, {"virtual", SCSPEC, RID_VIRTUAL,}, {"export", SCSPEC, RID_EXPORT,}, - {"and_eq", ASSIGN, NORID,}, - {"__typeof__", TYPEOF, NORID}, + {"and_eq", ASSIGN, RID_UNUSED,}, + {"__typeof__", TYPEOF, RID_UNUSED}, {"__const__", CV_QUALIFIER, RID_CONST}, {"__volatile", CV_QUALIFIER, RID_VOLATILE}, {"short", TYPESPEC, RID_SHORT,}, {"__volatile__", CV_QUALIFIER, RID_VOLATILE}, {"__const", CV_QUALIFIER, RID_CONST}, - {"namespace", NAMESPACE, NORID,}, + {"namespace", NAMESPACE, RID_UNUSED,}, {"char", TYPESPEC, RID_CHAR,}, {"unsigned", TYPESPEC, RID_UNSIGNED,}, {"double", TYPESPEC, RID_DOUBLE,}, - {"or_eq", ASSIGN, NORID,}, + {"or_eq", ASSIGN, RID_UNUSED,}, {"__null", CONSTANT, RID_NULL}, - {"if", IF, NORID,}, + {"if", IF, RID_UNUSED,}, {"__signature__", AGGR, RID_SIGNATURE /* Extension */,}, - {"__label__", LABEL, NORID}, + {"__label__", LABEL, RID_UNUSED}, {"long", TYPESPEC, RID_LONG,}, - {"__imag", IMAGPART, NORID}, - {"__asm", ASM_KEYWORD, NORID}, + {"__imag", IMAGPART, RID_UNUSED}, + {"__asm", ASM_KEYWORD, RID_UNUSED}, {"", 0, 0}, - {"__sigof__", SIGOF, NORID /* Extension */,}, + {"__sigof__", SIGOF, RID_UNUSED /* Extension */,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"struct", AGGR, RID_RECORD,}, {"", 0, 0}, {"volatile", CV_QUALIFIER, RID_VOLATILE,}, - {"false", CXX_FALSE, NORID,}, - {"sizeof", SIZEOF, NORID,}, + {"false", CXX_FALSE, RID_UNUSED,}, + {"sizeof", SIZEOF, RID_UNUSED,}, {"__complex__", TYPESPEC, RID_COMPLEX}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"for", FOR, NORID,}, - {"or", OROR, NORID,}, + {"for", FOR, RID_UNUSED,}, + {"or", OROR, RID_UNUSED,}, {"register", SCSPEC, RID_REGISTER,}, - {"throw", THROW, NORID,}, + {"throw", THROW, RID_UNUSED,}, {"", 0, 0}, - {"using", USING, NORID,}, + {"using", USING, RID_UNUSED,}, {"", 0, 0}, {"", 0, 0}, {"__complex", TYPESPEC, RID_COMPLEX}, {"", 0, 0}, - {"asm", ASM_KEYWORD, NORID,}, + {"asm", ASM_KEYWORD, RID_UNUSED,}, {"signature", AGGR, RID_SIGNATURE /* Extension */,}, - {"enum", ENUM, NORID,}, - {"reinterpret_cast", REINTERPRET_CAST, NORID,}, + {"enum", ENUM, RID_UNUSED,}, + {"reinterpret_cast", REINTERPRET_CAST, RID_UNUSED,}, {"mutable", SCSPEC, RID_MUTABLE,}, - {"__alignof", ALIGNOF, NORID}, - {"return", RETURN_KEYWORD, NORID,}, + {"__alignof", ALIGNOF, RID_UNUSED}, + {"return", RETURN_KEYWORD, RID_UNUSED,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"float", TYPESPEC, RID_FLOAT,}, @@ -199,26 +199,26 @@ is_reserved_word (str, len) {"bool", TYPESPEC, RID_BOOL,}, {"", 0, 0}, {"typedef", SCSPEC, RID_TYPEDEF,}, - {"__typeof", TYPEOF, NORID}, - {"bitand", '&', NORID,}, - {"break", BREAK, NORID,}, + {"__typeof", TYPEOF, RID_UNUSED}, + {"bitand", '&', RID_UNUSED,}, + {"break", BREAK, RID_UNUSED,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"union", AGGR, RID_UNION,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"goto", GOTO, NORID,}, - {"sigof", SIGOF, NORID /* Extension */,}, + {"goto", GOTO, RID_UNUSED,}, + {"sigof", SIGOF, RID_UNUSED /* Extension */,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"bitor", '|', NORID,}, + {"bitor", '|', RID_UNUSED,}, {"auto", SCSPEC, RID_AUTO,}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"operator", OPERATOR, NORID,} + {"operator", OPERATOR, RID_UNUSED,} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h index 249eef9bb0f..5c2a1d148c6 100644 --- a/gcc/cp/lex.h +++ b/gcc/cp/lex.h @@ -43,8 +43,9 @@ enum rid /* This is where grokdeclarator starts its search when setting the specbits. The first seven are in the order of most frequently used, as found building libg++. */ + RID_FIRST_MODIFIER, - RID_EXTERN, + RID_EXTERN = RID_FIRST_MODIFIER, RID_CONST, RID_LONG, RID_TYPEDEF, @@ -66,6 +67,7 @@ enum rid RID_COMPLEX, RID_RESTRICT, + RID_LAST_MODIFIER = RID_RESTRICT, /* This is where grokdeclarator ends its search when setting the specbits. */ @@ -81,11 +83,6 @@ enum rid RID_MAX }; -#define NORID RID_UNUSED - -#define RID_FIRST_MODIFIER RID_EXTERN -#define RID_LAST_MODIFIER RID_COMPLEX - /* The type that can represent all values of RIDBIT. */ /* We assume that we can stick in at least 32 bits into this. */ typedef struct { unsigned long idata[2]; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9698b965124..6db901c9299 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5311,7 +5311,8 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope) { tree r = build_ptrmemfunc_type (tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl)); - return cp_build_qualified_type (r, TYPE_QUALS (t)); + return cp_build_qualified_type_real (r, TYPE_QUALS (t), + complain); } /* else fall through */ @@ -5349,7 +5350,8 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope) entering_scope); pop_momentary (); - return cp_build_qualified_type (r, TYPE_QUALS (t)); + return cp_build_qualified_type_real (r, TYPE_QUALS (t), + complain); } else /* This is not a template type, so there's nothing to do. */ @@ -6208,18 +6210,9 @@ tsubst (t, args, complain, in_decl) { my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (arg)) == 't', 0); - - /* If we're not COMPLAINing, don't let an attempt - to qualify a FUNCTION_TYPE reach - cp_build_qualified_type. That will result in - an error message. */ - if (!complain - && TREE_CODE (arg) == FUNCTION_TYPE - && CP_TYPE_QUALS (t) != TYPE_UNQUALIFIED) - return error_mark_node; - - return cp_build_qualified_type - (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t)); + return cp_build_qualified_type_real + (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t), + complain); } else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM) { @@ -6244,7 +6237,9 @@ tsubst (t, args, complain, in_decl) argvec, in_decl, DECL_CONTEXT (arg), /*entering_scope=*/0); - return cp_build_qualified_type (r, TYPE_QUALS (t)); + return cp_build_qualified_type_real (r, + TYPE_QUALS (t), + complain); } else /* We are processing a template argument list. */ @@ -6411,7 +6406,7 @@ tsubst (t, args, complain, in_decl) r = build_pointer_type (type); else r = build_reference_type (type); - r = cp_build_qualified_type (r, TYPE_QUALS (t)); + r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); /* Will this ever be needed for TYPE_..._TO values? */ layout_type (r); @@ -6553,9 +6548,10 @@ tsubst (t, args, complain, in_decl) f = make_typename_type (ctx, f); if (f == error_mark_node) return f; - return cp_build_qualified_type (f, - CP_TYPE_QUALS (f) - | CP_TYPE_QUALS (t)); + return cp_build_qualified_type_real (f, + CP_TYPE_QUALS (f) + | CP_TYPE_QUALS (t), + complain); } case INDIRECT_REF: @@ -7388,6 +7384,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type, { tree parms; tree fntype; + int result; my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0); @@ -7446,9 +7443,25 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type, because the standard doesn't seem to explicitly prohibit it. Our callers must be ready to deal with unification failures in any event. */ - return type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), - targs, parms, args, /*subr=*/0, - strict, /*allow_incomplete*/1); + result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), + targs, parms, args, /*subr=*/0, + strict, /*allow_incomplete*/1); + + if (result == 0) + /* All is well so far. Now, check: + + [temp.deduct] + + When all template arguments have been deduced, all uses of + template parameters in nondeduced contexts are replaced with + the corresponding deduced argument values. If the + substitution results in an invalid type, as described above, + type deduction fails. */ + if (tsubst (TREE_TYPE (fn), targs, /*complain=*/0, NULL_TREE) + == error_mark_node) + return 1; + + return result; } /* Adjust types before performing type deduction, as described in @@ -8040,11 +8053,6 @@ check_cv_quals_for_unify (strict, arg, parm) && !at_least_as_qualified_p (parm, arg)) return 0; - /* Don't allow unification to create a qualified function type. */ - if (TREE_CODE (arg) == FUNCTION_TYPE - && CP_TYPE_QUALS (parm) != TYPE_UNQUALIFIED) - return 0; - return 1; } @@ -8198,9 +8206,12 @@ unify (tparms, targs, parm, arg, strict) /* Consider the case where ARG is `const volatile int' and PARM is `const T'. Then, T should be `volatile int'. */ arg = - cp_build_qualified_type (arg, - CP_TYPE_QUALS (arg) - & ~CP_TYPE_QUALS (parm)); + cp_build_qualified_type_real (arg, + CP_TYPE_QUALS (arg) + & ~CP_TYPE_QUALS (parm), + /*complain=*/0); + if (arg == error_mark_node) + return 1; } /* Simple cases: Value already set, does match or doesn't. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index a305cb5ca2c..9d77217e0a8 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -407,6 +407,9 @@ build_cplus_array_type_1 (elt_type, index_type) register struct obstack *ambient_saveable_obstack = saveable_obstack; tree t; + if (elt_type == error_mark_node || index_type == error_mark_node) + return error_mark_node; + /* We need a new one. If both ELT_TYPE and INDEX_TYPE are permanent, make this permanent too. */ if (TREE_PERMANENT (elt_type) @@ -454,13 +457,18 @@ build_cplus_array_type (elt_type, index_type) return t; } -/* Make a variant type in the proper way for C/C++, propagating qualifiers - down to the element type of an array. */ +/* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles + arrays correctly. In particular, if TYPE is an array of T's, and + TYPE_QUALS is non-empty, returns an array of qualified T's. If + at attempt is made to qualify a type illegally, and COMPLAIN is + non-zero, an error is issued. If COMPLAIN is zero, error_mark_node + is returned. */ tree -cp_build_qualified_type (type, type_quals) +cp_build_qualified_type_real (type, type_quals, complain) tree type; int type_quals; + int complain; { if (type == error_mark_node) return type; @@ -468,29 +476,40 @@ cp_build_qualified_type (type, type_quals) /* A restrict-qualified pointer type must be a pointer (or reference) to object or incomplete type. */ if ((type_quals & TYPE_QUAL_RESTRICT) + && TREE_CODE (type) != TEMPLATE_TYPE_PARM && (!POINTER_TYPE_P (type) || TYPE_PTRMEM_P (type) || TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)) { - cp_error ("`%T' cannot be `restrict'-qualified", type); + if (complain) + cp_error ("`%T' cannot be `restrict'-qualified", type); + else + return error_mark_node; + type_quals &= ~TYPE_QUAL_RESTRICT; } if (type_quals != TYPE_UNQUALIFIED && TREE_CODE (type) == FUNCTION_TYPE) { - cp_error ("`%T' cannot be `const'-, `volatile'-, or `restrict'-qualified", type); + if (complain) + cp_error ("`%T' cannot be `const'-, `volatile'-, or `restrict'-qualified", type); + else + return error_mark_node; type_quals = TYPE_UNQUALIFIED; } else if (TREE_CODE (type) == ARRAY_TYPE) { tree real_main_variant = TYPE_MAIN_VARIANT (type); - + tree element_type = cp_build_qualified_type_real (TREE_TYPE (type), + type_quals, + complain); push_obstacks (TYPE_OBSTACK (real_main_variant), TYPE_OBSTACK (real_main_variant)); - type = build_cplus_array_type_1 (cp_build_qualified_type - (TREE_TYPE (type), type_quals), + type = build_cplus_array_type_1 (element_type, TYPE_DOMAIN (type)); + if (type == error_mark_node) + return error_mark_node; /* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not, make a copy. (TYPE might have come from the hash table and -- 2.30.2