Re: C/C++ PATCH to add __remove_qualifiers (PR c/65455, c/39985)

2017-09-13 Thread Joseph Myers
This patch (for C) is setting c_inhibit_evaluation_warnings and 
in_remove_qualifiers and doing corresponding use of pop_maybe_used, but I 
don't see the need for that.  Expressions within the argument to 
__remove_qualifiers are evaluated exactly if they would be evaluated in 
the containing context; it's not like sizeof or typeof (expression) which 
can cause expressions not to be evaluated.  (I don't actually think any of 
that handling is needed for typeof (type) either, it simply happens that 
the initial adjustments of c_inhibit_evaluation_warnings and in_typeof are 
done in code shared by typeof (expression) and typeof (type).)

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: C/C++ PATCH to add __remove_qualifiers (PR c/65455, c/39985)

2017-09-13 Thread Joseph Myers
On Sat, 9 Sep 2017, Jason Merrill wrote:

> > +@code{__remove_qualifiers} takes a typename as an argument:
> 
> I think it would be better to use the term "type-id" here, to avoid
> confusion with "type-name", which is only a single identifier.

There's no such thing as a type-id in C, and type-name is the term used in 
C syntax (for what goes in a cast, etc.).

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: C/C++ PATCH to add __remove_qualifiers (PR c/65455, c/39985)

2017-09-09 Thread Jason Merrill
On Fri, Sep 1, 2017 at 2:46 PM, Marek Polacek  wrote:
> @@ -16960,6 +16961,24 @@ cp_parser_simple_type_specifier (cp_parser* parser,
>
>return type;
>
> +case RID_REMOVE_QUALS:
> +  /* Consume the `__remove_qualifiers' token.  */
> +  cp_lexer_consume_token (parser->lexer);
> +  /* Parse the operand to __remove_qualifiers`'.  */
> +  type = cp_parser_sizeof_operand (parser, RID_REMOVE_QUALS);

Wouldn't it be simpler to use cp_parser_type_id?

> +  if (!TYPE_P (type))
> +   {
> + error_at (token->location,
> +   "%<__remove_qualifiers%> can only be applied to a type");
> + type = error_mark_node;
> +   }

...rather than check this.

It doesn't look like you handle use of __remove_qualifiers in a
template, and you don't have any testcases for it.

> +@code{__remove_qualifiers} takes a typename as an argument:

I think it would be better to use the term "type-id" here, to avoid
confusion with "type-name", which is only a single identifier.

Jason


Re: C/C++ PATCH to add __remove_qualifiers (PR c/65455, c/39985)

2017-09-01 Thread Marek Polacek
On Thu, Aug 31, 2017 at 04:38:27PM +, Joseph Myers wrote:
> I think the documentation needs to say (and the tests need to test) that 
> this produces a non-atomic type (like lvalue-to-rvalue conversion), if 
> that's the intent for how it handles atomic types, since _Atomic is 
> syntactically a qualifier but largely not treated like one in the 
> standard.

True, updated patch here:

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-09-01  Marek Polacek  

PR c/39985
PR c/65455
* c-common.c (c_common_reswords): Add __remove_qualifiers and
__remove_qualifiers__.
(keyword_begins_type_specifier): Handle RID_REMOVE_QUALS.
* c-common.h (enum rid): Add RID_REMOVE_QUALS.

* c-decl.c (start_struct): Also check in_remove_qualifiers.
(finish_struct): Likewise.
(start_enum): Likewise.
(finish_enum): Likewise.
* c-parser.c (c_keyword_starts_typename): Handle RID_REMOVE_QUALS.
(c_token_starts_declspecs): Likewise.
(c_parser_declaration_or_fndef): For __auto_type, remove all type
qualifiers.
(c_parser_declspecs): Handle RID_REMOVE_QUALS.
(c_parser_remove_qualifiers_specifier): New function.
(c_parser_objc_selector): Handle RID_REMOVE_QUALS.
* c-tree.h (enum c_typespec_kind): Update a comment.
Declare in_remove_qualifiers.
* c-typeck.c (in_remove_qualifiers): New global variable.
(build_external_ref): Also check in_remove_qualifiers.
(struct maybe_used_decl): Likewise.
(record_maybe_used_decl): Likewise.
(pop_maybe_used): Likewise.

* parser.c (cp_keyword_starts_decl_specifier_p): Handle
RID_REMOVE_QUALS.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_sizeof_operand): For __remove_qualifiers, remove all type
qualifiers.

* doc/extend.texi: Document __remove_qualifiers.

* c-c++-common/remove-quals-1.c: New test.
* c-c++-common/remove-quals-2.c: New test.
* c-c++-common/remove-quals-3.c: New test.
* c-c++-common/remove-quals-4.c: New test.
* g++.dg/ext/remove-quals-1.C: New test.
* g++.dg/ext/remove-quals-2.C: New test.
* gcc.dg/auto-type-3.c: New test.
* gcc.dg/remove-quals-1.c: New test.
* gcc.dg/remove-quals-2.c: New test.
* gcc.dg/remove-quals-3.c: New test.

diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index d959dbc25bb..ae92ff440f6 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -423,6 +423,8 @@ const struct c_common_resword c_common_reswords[] =
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
+  { "__remove_qualifiers", RID_REMOVE_QUALS, 0 },
+  { "__remove_qualifiers__", RID_REMOVE_QUALS, 0 },
   { "__restrict",  RID_RESTRICT,   0 },
   { "__restrict__",RID_RESTRICT,   0 },
   { "__signed",RID_SIGNED, 0 },
@@ -7525,6 +7527,7 @@ keyword_begins_type_specifier (enum rid keyword)
 case RID_CLASS:
 case RID_UNION:
 case RID_ENUM:
+case RID_REMOVE_QUALS:
   return true;
 default:
   if (keyword >= RID_FIRST_INT_N
diff --git gcc/c-family/c-common.h gcc/c-family/c-common.h
index 8e367680600..e726aa8844b 100644
--- gcc/c-family/c-common.h
+++ gcc/c-family/c-common.h
@@ -101,7 +101,7 @@ enum rid
   RID_ASM,   RID_TYPEOF,   RID_ALIGNOF,  RID_ATTRIBUTE,  RID_VA_ARG,
   RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,  RID_CHOOSE_EXPR,
   RID_TYPES_COMPATIBLE_P,  RID_BUILTIN_COMPLEX, 
RID_BUILTIN_SHUFFLE,
-  RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
+  RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,  RID_REMOVE_QUALS,
 
   /* TS 18661-3 keywords, in the same sequence as the TI_* values.  */
   RID_FLOAT16,
diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index d526f0e88e4..b9cd5f8cf56 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -7516,12 +7516,14 @@ start_struct (location_t loc, enum tree_code code, tree 
name,
  within a statement expr used within sizeof, et. al.  This is not
  terribly serious as C++ doesn't permit statement exprs within
  sizeof anyhow.  */
-  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof))
+  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof
+ || in_remove_qualifiers))
 warning_at (loc, OPT_Wc___compat,
"defining type in %qs expression is invalid in C++",
-   (in_sizeof
-? "sizeof"
-: (in_typeof ? "typeof" : "alignof")));
+   (in_sizeof ? "sizeof"
+: (in_typeof ? "typeof"
+ : (in_alignof ? "alignof"
+   : "__remove_qualifiers";
 
   return ref;
 }
@@ -8159,7 +8161,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree 

Re: C/C++ PATCH to add __remove_qualifiers (PR c/65455, c/39985)

2017-08-31 Thread Joseph Myers
I think the documentation needs to say (and the tests need to test) that 
this produces a non-atomic type (like lvalue-to-rvalue conversion), if 
that's the intent for how it handles atomic types, since _Atomic is 
syntactically a qualifier but largely not treated like one in the 
standard.

-- 
Joseph S. Myers
jos...@codesourcery.com


C/C++ PATCH to add __remove_qualifiers (PR c/65455, c/39985)

2017-08-31 Thread Marek Polacek
After a long time, I'm finally sending the revisited patch dealing with these
two PRs.  To quickly recap, users were looking for a typeof variant that
strips type qualifiers.  I sent a path adding __typeof_noqual, but a discussion
ensued and it's been concluded that we'd rather go a different way, i.e. add
__remove_qualifiers, which takes a typename, and strips type qualifiers.  That
is my understanding anyway.  Here's a patch implementing just that, for both
C and C++ FEs.

Here's a link to the previous discussion:
https://gcc.gnu.org/ml/gcc-patches/2017-07/msg01146.html

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-08-31  Marek Polacek  

PR c/39985
PR c/65455
* c-common.c (c_common_reswords): Add __remove_qualifiers and
__remove_qualifiers__.
(keyword_begins_type_specifier): Handle RID_REMOVE_QUALS.
* c-common.h (enum rid): Add RID_REMOVE_QUALS.

* c-decl.c (start_struct): Also check in_remove_qualifiers.
(finish_struct): Likewise.
(start_enum): Likewise.
(finish_enum): Likewise.
* c-parser.c (c_keyword_starts_typename): Handle RID_REMOVE_QUALS.
(c_token_starts_declspecs): Likewise.
(c_parser_declaration_or_fndef): For __auto_type, remove all type
qualifiers.
(c_parser_declspecs): Handle RID_REMOVE_QUALS.
(c_parser_remove_qualifiers_specifier): New function.
(c_parser_objc_selector): Handle RID_REMOVE_QUALS.
* c-tree.h (enum c_typespec_kind): Update a comment.
Declare in_remove_qualifiers.
* c-typeck.c (in_remove_qualifiers): New global variable.
(build_external_ref): Also check in_remove_qualifiers.
(struct maybe_used_decl): Likewise.
(record_maybe_used_decl): Likewise.
(pop_maybe_used): Likewise.

* parser.c (cp_keyword_starts_decl_specifier_p): Handle
RID_REMOVE_QUALS.
(cp_parser_simple_type_specifier): Likewise.
(cp_parser_sizeof_operand): For __remove_qualifiers, remove all type
qualifiers.

* doc/extend.texi: Document __remove_qualifiers.

* c-c++-common/remove-quals-1.c: New test.
* c-c++-common/remove-quals-2.c: New test.
* c-c++-common/remove-quals-3.c: New test.
* c-c++-common/remove-quals-4.c: New test.
* g++.dg/ext/remove-quals-1.C: New test.
* g++.dg/ext/remove-quals-2.C: New test.
* gcc.dg/auto-type-3.c: New test.
* gcc.dg/remove-quals-1.c: New test.
* gcc.dg/remove-quals-2.c: New test.

diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index d959dbc25bb..ae92ff440f6 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -423,6 +423,8 @@ const struct c_common_resword c_common_reswords[] =
   { "__null",  RID_NULL,   0 },
   { "__real",  RID_REALPART,   0 },
   { "__real__",RID_REALPART,   0 },
+  { "__remove_qualifiers", RID_REMOVE_QUALS, 0 },
+  { "__remove_qualifiers__", RID_REMOVE_QUALS, 0 },
   { "__restrict",  RID_RESTRICT,   0 },
   { "__restrict__",RID_RESTRICT,   0 },
   { "__signed",RID_SIGNED, 0 },
@@ -7525,6 +7527,7 @@ keyword_begins_type_specifier (enum rid keyword)
 case RID_CLASS:
 case RID_UNION:
 case RID_ENUM:
+case RID_REMOVE_QUALS:
   return true;
 default:
   if (keyword >= RID_FIRST_INT_N
diff --git gcc/c-family/c-common.h gcc/c-family/c-common.h
index 8e367680600..e726aa8844b 100644
--- gcc/c-family/c-common.h
+++ gcc/c-family/c-common.h
@@ -101,7 +101,7 @@ enum rid
   RID_ASM,   RID_TYPEOF,   RID_ALIGNOF,  RID_ATTRIBUTE,  RID_VA_ARG,
   RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL,  RID_CHOOSE_EXPR,
   RID_TYPES_COMPATIBLE_P,  RID_BUILTIN_COMPLEX, 
RID_BUILTIN_SHUFFLE,
-  RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
+  RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,  RID_REMOVE_QUALS,
 
   /* TS 18661-3 keywords, in the same sequence as the TI_* values.  */
   RID_FLOAT16,
diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index d526f0e88e4..b9cd5f8cf56 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -7516,12 +7516,14 @@ start_struct (location_t loc, enum tree_code code, tree 
name,
  within a statement expr used within sizeof, et. al.  This is not
  terribly serious as C++ doesn't permit statement exprs within
  sizeof anyhow.  */
-  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof))
+  if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof
+ || in_remove_qualifiers))
 warning_at (loc, OPT_Wc___compat,
"defining type in %qs expression is invalid in C++",
-   (in_sizeof
-? "sizeof"
-: (in_typeof ? "typeof" : "alignof")));
+   (in_sizeof ? "sizeof"
+: (in_typeof ? "typeof"
+ : (in_alignof ? "alignof"
+