Hi,
On 09/10/18 17:17, Jason Merrill wrote:
On Sat, Sep 29, 2018 at 3:27 PM Paolo Carlini <paolo.carl...@oracle.com> wrote:
Hi again,
On 9/28/18 9:15 PM, Paolo Carlini wrote:
Thanks. About the location, you are certainly right, but doesn't seem
trivial. Something we can do *now* is using
declspecs->locations[ds_typedef] and declspecs->locations[ds_alias],
but that gives us the location of the keyword 'typedef' and 'using',
respectively, whereas I think that we would like to have the location
of 'auto' itself. I could look into that as a follow-up piece work
In fact, completing the work turned out to be easy: ensure that
cp_parser_alias_declaration saves the location of the defining-type-id
too and then consistently use locations[ds_type_spec] in the error
messages. Tested x86_64-linux. Still Ok? ;)
Hmm, I think you need to look past any cv-qualifiers at the beginning
of the type-id.
Ah, good point. The information is readily available in
cp_parser_type_id thus we can simply return it to
cp_parser_alias_declaration. I guess an alternate approach would be
adding a pointer to the whole cp_decl_specifier_seq parameter to
cp_parser_type_id (and cp_parser_type_id_1, etc), but that seems over
killing to me.
Thanks! Paolo.
/////////////////////
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 264985)
+++ cp/decl.c (working copy)
@@ -11879,6 +11879,7 @@ grokdeclarator (const cp_declarator *declarator,
/* If this is declaring a typedef name, return a TYPE_DECL. */
if (typedef_p && decl_context != TYPENAME)
{
+ bool alias_p = decl_spec_seq_has_spec_p (declspecs, ds_alias);
tree decl;
/* This declaration:
@@ -11901,7 +11902,12 @@ grokdeclarator (const cp_declarator *declarator,
if (type_uses_auto (type))
{
- error ("typedef declared %<auto%>");
+ if (alias_p)
+ error_at (declspecs->locations[ds_type_spec],
+ "%<auto%> not allowed in alias declaration");
+ else
+ error_at (declspecs->locations[ds_type_spec],
+ "typedef declared %<auto%>");
type = error_mark_node;
}
@@ -11961,7 +11967,7 @@ grokdeclarator (const cp_declarator *declarator,
inlinep, friendp, raises != NULL_TREE,
declspecs->locations);
- if (decl_spec_seq_has_spec_p (declspecs, ds_alias))
+ if (alias_p)
/* Acknowledge that this was written:
`using analias = atype;'. */
TYPE_DECL_ALIAS_P (decl) = 1;
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 264985)
+++ cp/parser.c (working copy)
@@ -2216,12 +2216,12 @@ static tree cp_parser_late_return_type_opt
static tree cp_parser_declarator_id
(cp_parser *, bool);
static tree cp_parser_type_id
- (cp_parser *);
+ (cp_parser *, location_t * = NULL);
static tree cp_parser_template_type_arg
(cp_parser *);
static tree cp_parser_trailing_type_id (cp_parser *);
static tree cp_parser_type_id_1
- (cp_parser *, bool, bool);
+ (cp_parser *, bool, bool, location_t *);
static void cp_parser_type_specifier_seq
(cp_parser *, bool, bool, cp_decl_specifier_seq *);
static tree cp_parser_parameter_declaration_clause
@@ -19034,7 +19034,7 @@ static tree
cp_parser_alias_declaration (cp_parser* parser)
{
tree id, type, decl, pushed_scope = NULL_TREE, attributes;
- location_t id_location;
+ location_t id_location, type_location;
cp_declarator *declarator;
cp_decl_specifier_seq decl_specs;
bool member_p;
@@ -19086,7 +19086,7 @@ cp_parser_alias_declaration (cp_parser* parser)
G_("types may not be defined in alias template declarations");
}
- type = cp_parser_type_id (parser);
+ type = cp_parser_type_id (parser, &type_location);
/* Restore the error message if need be. */
if (parser->num_template_parameter_lists)
@@ -19120,6 +19120,7 @@ cp_parser_alias_declaration (cp_parser* parser)
set_and_check_decl_spec_loc (&decl_specs,
ds_alias,
using_token);
+ decl_specs.locations[ds_type_spec] = type_location;
if (parser->num_template_parameter_lists
&& !cp_parser_check_template_parameters (parser,
@@ -21110,7 +21111,7 @@ cp_parser_declarator_id (cp_parser* parser, bool o
static tree
cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
- bool is_trailing_return)
+ bool is_trailing_return, location_t * type_location)
{
cp_decl_specifier_seq type_specifier_seq;
cp_declarator *abstract_declarator;
@@ -21119,6 +21120,9 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_te
cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
is_trailing_return,
&type_specifier_seq);
+ if (type_location)
+ *type_location = type_specifier_seq.locations[ds_type_spec];
+
if (is_template_arg && type_specifier_seq.type
&& TREE_CODE (type_specifier_seq.type) == TEMPLATE_TYPE_PARM
&& CLASS_PLACEHOLDER_TEMPLATE (type_specifier_seq.type))
@@ -21184,9 +21188,9 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_te
}
static tree
-cp_parser_type_id (cp_parser *parser)
+cp_parser_type_id (cp_parser *parser, location_t * type_location)
{
- return cp_parser_type_id_1 (parser, false, false);
+ return cp_parser_type_id_1 (parser, false, false, type_location);
}
static tree
@@ -21196,7 +21200,7 @@ cp_parser_template_type_arg (cp_parser *parser)
const char *saved_message = parser->type_definition_forbidden_message;
parser->type_definition_forbidden_message
= G_("types may not be defined in template arguments");
- r = cp_parser_type_id_1 (parser, true, false);
+ r = cp_parser_type_id_1 (parser, true, false, NULL);
parser->type_definition_forbidden_message = saved_message;
if (cxx_dialect >= cxx14 && !flag_concepts && type_uses_auto (r))
{
@@ -21209,7 +21213,7 @@ cp_parser_template_type_arg (cp_parser *parser)
static tree
cp_parser_trailing_type_id (cp_parser *parser)
{
- return cp_parser_type_id_1 (parser, false, true);
+ return cp_parser_type_id_1 (parser, false, true, NULL);
}
/* Parse a type-specifier-seq.
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 264985)
+++ cp/pt.c (working copy)
@@ -7776,7 +7776,7 @@ convert_template_argument (tree parm,
tree val;
int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
- if (parm == error_mark_node)
+ if (parm == error_mark_node || error_operand_p (arg))
return error_mark_node;
/* Trivially convert placeholders. */
Index: testsuite/g++.dg/concepts/pr84423-1.C
===================================================================
--- testsuite/g++.dg/concepts/pr84423-1.C (nonexistent)
+++ testsuite/g++.dg/concepts/pr84423-1.C (working copy)
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fconcepts" }
+
+template<typename> using A = auto; // { dg-error "30:.auto. not allowed in
alias declaration" }
+
+template<template<typename> class> struct B {};
+
+B<A> b;
Index: testsuite/g++.dg/concepts/pr84423-2.C
===================================================================
--- testsuite/g++.dg/concepts/pr84423-2.C (nonexistent)
+++ testsuite/g++.dg/concepts/pr84423-2.C (working copy)
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fconcepts" }
+
+using A = auto; // { dg-error "11:.auto. not allowed in alias declaration" }
+
+using A1 = const auto; // { dg-error "18:.auto. not allowed in alias
declaration" }
+
+using A2 = volatile auto; // { dg-error "21:.auto. not allowed in alias
declaration" }
+
+using A3 = const volatile auto; // { dg-error "27:.auto. not allowed in alias
declaration" }
+
+typedef auto B; // { dg-error "9:typedef declared .auto." }
+
+typedef const auto B1; // { dg-error "15:typedef declared .auto." }
+
+typedef volatile auto B2; // { dg-error "18:typedef declared .auto." }
+
+typedef const volatile auto B3; // { dg-error "24:typedef declared .auto." }
Index: testsuite/g++.dg/cpp0x/auto39.C
===================================================================
--- testsuite/g++.dg/cpp0x/auto39.C (revision 264985)
+++ testsuite/g++.dg/cpp0x/auto39.C (working copy)
@@ -1,6 +1,6 @@
// PR c++/58560
// { dg-do compile { target c++11 } }
-typedef auto T; // { dg-error "typedef declared 'auto'" }
+typedef auto T; // { dg-error "9:typedef declared 'auto'" }
void foo() { T(); }
Index: testsuite/g++.dg/cpp0x/auto9.C
===================================================================
--- testsuite/g++.dg/cpp0x/auto9.C (revision 264985)
+++ testsuite/g++.dg/cpp0x/auto9.C (working copy)
@@ -120,4 +120,4 @@ void qq (auto); // { dg-error "auto" "" {
void qr (auto*); // { dg-error "auto" "" { target { ! concepts }
} }
// PR c++/46145
-typedef auto autot; // { dg-error "auto" }
+typedef auto autot; // { dg-error "9:typedef declared .auto." }
Index: testsuite/g++.dg/cpp1y/pr60384.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr60384.C (revision 264985)
+++ testsuite/g++.dg/cpp1y/pr60384.C (working copy)
@@ -5,5 +5,5 @@ template<typename> int foo();
struct A
{
- typedef auto foo<>(); // { dg-error "typedef declared 'auto'" }
+ typedef auto foo<>(); // { dg-error "11:typedef declared 'auto'" }
};