Patchwork [C++] Fixes for duplicate warnings regressions [1/2]

login
register
mail settings
Submitter Paolo Carlini
Date Nov. 25, 2013, 10:02 a.m.
Message ID <52932044.9080003@oracle.com>
Download mbox | patch
Permalink /patch/293872/
State New
Headers show

Comments

Paolo Carlini - Nov. 25, 2013, 10:02 a.m.
On 11/23/2013 08:12 PM, Jason Merrill wrote:
> On 11/10/2013 05:26 AM, Paolo Carlini wrote:
>> this is the issue with -Waddress caused by the fix for c++/56930. I'm
>> handling it as already described, that is by adding a bool parameter to
>> c_common_truthvalue_conversion.
>
> Why not handle this by making that warning respect 
> c_inhibit_evaluation_warnings?

Good question, but it doesn't work, in the sense that we can't simply 
protect the warning itself with "c_inhibit_evaluation_warnings == 0" 
(per the attached) and bump the global around the second cp_convert, 
because then we don't warn *at all*. The reason being that with the 
*first* cp_convert we end up calling c_common_truthvalue_conversion with 
c_inhibit_evaluation_warnings bumped. The bumping happens in 
cp_truthvalue_conversion. A mess, yes. At this Stage, if we don't feel 
like going with something like my last try or something even less 
straightforward reworking the way we bump c_inhibit_evaluation_warnings 
in the various circumstances, I'm tempted to go back to my first try:

-      tree folded_result = cp_convert (type, folded, complain);
+      tree folded_result
+	= folded != expr ? cp_convert (type, folded, complain) : result;


Would it be safe? I mean, is it at all possible that folded == expr and 
in fact we should call again cp_convert? Because otherwise it's also a 
(minor) optimization and radically avoids the problem.

Paolo.
Jason Merrill - Nov. 25, 2013, 9:47 p.m.
On 11/25/2013 05:02 AM, Paolo Carlini wrote:
> because then we don't warn *at all*. The reason being that with the
> *first* cp_convert we end up calling c_common_truthvalue_conversion with
> c_inhibit_evaluation_warnings bumped. The bumping happens in
> cp_truthvalue_conversion. A mess, yes.

Perhaps cp_truthvalue_conversion should do something more specific to 
the actual warning it's trying to avoid.

> At this Stage, if we don't feel
> like going with something like my last try or something even less
> straightforward reworking the way we bump c_inhibit_evaluation_warnings
> in the various circumstances, I'm tempted to go back to my first try:
>
> -      tree folded_result = cp_convert (type, folded, complain);
> +      tree folded_result
> +    = folded != expr ? cp_convert (type, folded, complain) : result;
>
> Would it be safe? I mean, is it at all possible that folded == expr and
> in fact we should call again cp_convert? Because otherwise it's also a
> (minor) optimization and radically avoids the problem.

That's fine with me.

Jason
Paolo Carlini - Nov. 26, 2013, 9:53 a.m.
Hi,

On 11/25/2013 10:47 PM, Jason Merrill wrote:
> On 11/25/2013 05:02 AM, Paolo Carlini wrote:
>> because then we don't warn *at all*. The reason being that with the
>> *first* cp_convert we end up calling c_common_truthvalue_conversion with
>> c_inhibit_evaluation_warnings bumped. The bumping happens in
>> cp_truthvalue_conversion. A mess, yes.
> Perhaps cp_truthvalue_conversion should do something more specific to 
> the actual warning it's trying to avoid.
Agreed, I'll investigate.
>> At this Stage, if we don't feel
>> like going with something like my last try or something even less
>> straightforward reworking the way we bump c_inhibit_evaluation_warnings
>> in the various circumstances, I'm tempted to go back to my first try:
>>
>> -      tree folded_result = cp_convert (type, folded, complain);
>> +      tree folded_result
>> +    = folded != expr ? cp_convert (type, folded, complain) : result;
>>
>> Would it be safe? I mean, is it at all possible that folded == expr and
>> in fact we should call again cp_convert? Because otherwise it's also a
>> (minor) optimization and radically avoids the problem.
>
> That's fine with me.
Ok.Then, first I'm going to commit this tweak: if we agree that it does 
what I thought it does, it cannot hurt.

Paolo.

Patch

Index: parser.c
===================================================================
--- parser.c	(revision 204780)
+++ parser.c	(working copy)
@@ -23378,12 +23378,16 @@  cp_parser_late_parsing_nsdmi (cp_parser *parser, t
 {
   tree def;
 
+  maybe_begin_member_template_processing (field);
+
   push_unparsed_function_queues (parser);
   def = cp_parser_late_parse_one_default_arg (parser, field,
 					      DECL_INITIAL (field),
 					      NULL_TREE);
   pop_unparsed_function_queues (parser);
 
+  maybe_end_member_template_processing ();
+
   DECL_INITIAL (field) = def;
 }
 
Index: pt.c
===================================================================
--- pt.c	(revision 204780)
+++ pt.c	(working copy)
@@ -151,7 +151,7 @@  static int for_each_template_parm (tree, tree_fn_t
 				   struct pointer_set_t*, bool);
 static tree expand_template_argument_pack (tree);
 static tree build_template_parm_index (int, int, int, tree, tree);
-static bool inline_needs_template_parms (tree);
+static bool inline_needs_template_parms (tree, bool);
 static void push_inline_template_parms_recursive (tree, int);
 static tree retrieve_local_specialization (tree);
 static void register_local_specialization (tree, tree);
@@ -377,9 +377,9 @@  template_class_depth (tree type)
    Returns true if processing DECL needs us to push template parms.  */
 
 static bool
-inline_needs_template_parms (tree decl)
+inline_needs_template_parms (tree decl, bool nsdmi)
 {
-  if (! DECL_TEMPLATE_INFO (decl))
+  if (!decl || (!nsdmi && ! DECL_TEMPLATE_INFO (decl)))
     return false;
 
   return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl)))
@@ -448,16 +448,23 @@  push_inline_template_parms_recursive (tree parmlis
     }
 }
 
-/* Restore the template parameter context for a member template or
-   a friend template defined in a class definition.  */
+/* Restore the template parameter context for a member template, a
+   friend template defined in a class definition, or a non-template
+   member of template class.  */
 
 void
 maybe_begin_member_template_processing (tree decl)
 {
   tree parms;
   int levels = 0;
+  bool nsdmi = TREE_CODE (decl) == FIELD_DECL;
 
-  if (inline_needs_template_parms (decl))
+  if (nsdmi)
+    decl = (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
+	    ? TREE_TYPE (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)))
+	    : NULL_TREE);
+
+  if (inline_needs_template_parms (decl, nsdmi))
     {
       parms = DECL_TEMPLATE_PARMS (most_general_template (decl));
       levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl;