Bug 86567 - [8/9 Regression] -Wnonnull/-Wformat/-Wrestrict affect code generation
Summary: [8/9 Regression] -Wnonnull/-Wformat/-Wrestrict affect code generation
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.1.1
: P2 normal
Target Milestone: 8.4
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on: 56856
Blocks: 86518
  Show dependency treegraph
 
Reported: 2018-07-18 11:27 UTC by Alexander Monakov
Modified: 2023-10-31 12:56 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-07-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Monakov 2018-07-18 11:27:26 UTC
#include <vector>

std::vector<int>
f()
{
  std::vector<int> r;
  return r;
}

starting with gcc-8 ICEs using 'g++ -fcompare-debug=-Wnonnull' (as well as Wformat, Wrestrict, Wsuggest-attribute=format)


cp/call.c:build_over_call() has:

  if (warn_nonnull
      || warn_format
      || warn_suggest_attribute_format
      || warn_restrict)
    {
      tree *fargs = (!nargs ? argarray
                            : (tree *) alloca (nargs * sizeof (tree)));
      for (j = 0; j < nargs; j++)
        {
          /* For -Wformat undo the implicit passing by hidden reference
             done by convert_arg_to_ellipsis.  */
          if (TREE_CODE (argarray[j]) == ADDR_EXPR
              && TYPE_REF_P (TREE_TYPE (argarray[j])))
            fargs[j] = TREE_OPERAND (argarray[j], 0);
          else
            fargs[j] = maybe_constant_value (argarray[j]);
        }

      warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn),
                                           nargs, fargs, NULL);
    }


which if bypassed does not cause the ICE, which indicates that something in the snippet may affect code generation (not investigating further).
Comment 1 Richard Biener 2018-07-18 11:57:15 UTC
I think maybe_constant_value has a cache which may cause side-effects.
Comment 2 Martin Sebor 2018-07-18 15:06:40 UTC
Confirmed (both the error and that maybe_constant_value has a cache).

$ cat t.C && gcc -S -fcompare-debug=-Wrestrict t.C
#include <vector>

std::vector<int>
f()
{
  std::vector<int> r;
  return r;
}
xg++: error: t.C: -fcompare-debug failure
Comment 3 Jakub Jelinek 2018-07-26 11:20:13 UTC
GCC 8.2 has been released.
Comment 4 Alexander Monakov 2018-09-25 15:16:07 UTC
I think the problem is not exactly that maybe_constant_value keeps a lookup cache, but rather that invoking maybe_constant_value may cause allocation of uids. So it wouldn't be enough to simply avoid populating the cache in warning context.

It seems a bit strange to do full-blown constexpr evaluation for warnings, especially if normal compilation flow wouldn't perform the same evaluation. Wouldn't it make sense to use some more light-weight lookup for warning purposes?

On this testcase we allocate a new uid via

allocate_decl_uid ()
make_node (code=RESULT_DECL)
build_decl (loc=13709891, code=RESULT_DECL, name=0x0, type=0x7ffff0d86e70)
start_preparsed_function(tree_node*, tree_node*, int) ()
instantiate_decl(tree_node*, bool, bool) ()
instantiate_cx_fn_r (tp=0x7ffff0d88c98, walk_subtrees=0x7fffffffd528)
walk_tree_1
walk_tree_1
walk_tree_1
walk_tree_without_duplicates_1
instantiate_constexpr_fns (t=0x7ffff0d88ea0)
cxx_eval_outermost_constant_expr
maybe_constant_value (t=0x7ffff0d88ea0, decl=0x0)
build_over_call (cand=0x27a65a0, flags=1, complain=3)
build_new_method_call_1
build_new_method_call
build_special_member_call
expand_aggr_init_1(tree_node*, tree_node*, tree_node*, tree_node*, int, int) ()
emit_mem_initializers(tree_node*) ()
tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) ()
tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) ()
instantiate_decl(tree_node*, bool, bool) ()
instantiate_pending_templates(int) ()
c_parse_final_cleanups() ()
compile_file() ()
toplev::main(int, char**) ()
main ()
Comment 5 Jason Merrill 2018-10-29 17:47:17 UTC
(In reply to Alexander Monakov from comment #4)
> It seems a bit strange to do full-blown constexpr evaluation for warnings,
> especially if normal compilation flow wouldn't perform the same evaluation.

If the warning might depend on a constant value, we try to come up with a constant value for it.
Comment 6 Jakub Jelinek 2019-02-22 15:21:54 UTC
GCC 8.3 has been released.
Comment 7 Jason Merrill 2019-04-03 17:11:31 UTC
Fixed for GCC 9 by the patch for PR 56856, which removed that call to maybe_constant_value.  Not worth backporting.