[Bug c++/104384] coroutines: Heap corruption when initializing struct with co_await

2023-04-22 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104384

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #1 from Steven Sun  ---
seems that 103909, 104384, 107288 are related (probably the same bug)

[Bug c++/107288] coroutines: Double-free of temporaries created in statement following co_await

2023-04-22 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107288

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #3 from Steven Sun  ---
seems that 103909, 104384, 107288 are related (probably the same bug)

[Bug c++/103909] coroutines: co_yield of aggregate-initialized temporaries leads to segmentation faults.

2023-04-22 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103909

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #3 from Steven Sun  ---
seems that 103909, 104384, 107288 are related (probably the same bug)

[Bug analyzer/109027] [13 Regression] ICE: SIGSEGV (infinite recursion in ana::constraint_manager::eval_condition / ana::constraint_manager::impossible_derived_conditions_p) with -fanalyzer since r13-

2023-04-15 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109027

--- Comment #3 from Steven Sun  ---
Oh, my reduced test case has the same infinite recursion occurring, where

the `a+4` is

binop_svalue (pointer_plus_expr, unaryop_svalue (nop_expr, conjured_svalue (,
_iterator::_iterator (&__position, 0);,
decl_region(frame_region(‘Vector::Filter’, index: 2, depth: 3), ‘struct
iterator’, ‘iterator __position’))), constant_svalue(‘long unsigned int’, 4))

the `b-4` is

binop_svalue (pointer_plus_expr, sub_svalue (, conjured_svalue (,
_iterator::_iterator (&__position, 0);, decl_region(globals, ‘struct Vector’,
‘Vector vec’)), field_region(decl_region(globals, ‘struct Vector’, ‘Vector
vec’), ‘int *’, ‘int* Vector::_M_finish’)), constant_svalue(‘sizetype’,
18446744073709551612))



Current m_equiv_classes dump:

 new equiv_class 
region_svalue(‘struct Vector *’, decl_region(globals, ‘struct Vector’, ‘Vector
vec’))

 new equiv_class 
constant_svalue(‘void *’, 0B)

 new equiv_class 
region_svalue(‘struct _iterator *’, decl_region(frame_region(‘Vector::Filter’,
index: 2, depth: 3), ‘struct _iterator’, ‘’))

 new equiv_class 
region_svalue(‘int * *’, field_region(decl_region(globals, ‘struct Vector’,
‘Vector vec’), ‘int *’, ‘int* Vector::_M_finish’))

 new equiv_class 
region_svalue(‘struct _iterator *’, decl_region(frame_region(‘Vector::Filter’,
index: 2, depth: 3), ‘struct _iterator’, ‘_iterator it’))

 new equiv_class 
sub_svalue (, conjured_svalue (, it = Vector::begin (this_10(D));,
decl_region(frame_region(‘Vector::Filter’, index: 2, depth: 3), ‘struct
_iterator’, ‘_iterator it’)),
field_region(decl_region(frame_region(‘Vector::Filter’, index: 2, depth: 3),
‘struct _iterator’, ‘_iterator it’), ‘int *’, ‘int* _iterator::_M_current’))

 new equiv_class 
sub_svalue (, conjured_svalue (, it = Vector::begin (this_10(D));,
decl_region(globals, ‘struct Vector’, ‘Vector vec’)),
cast_region(field_region(decl_region(globals, ‘struct Vector’, ‘Vector vec’),
‘int *’, ‘int* Vector::_M_finish’), ‘int * const’))

 new equiv_class 
region_svalue(‘struct _iterator *’, decl_region(frame_region(‘Vector::Filter’,
index: 2, depth: 3), ‘struct _iterator’, ‘’))

 new equiv_class 
region_svalue(‘struct iterator *’, decl_region(frame_region(‘Vector::Filter’,
index: 2, depth: 3), ‘struct iterator’, ‘iterator __position’))

 new equiv_class 
region_svalue(‘struct _iterator *’,
decl_region(frame_region(‘_iterator::operator+’, index: 3, depth: 4), ‘struct
_iterator’, ‘’))

 new equiv_class 
region_svalue(‘int * const *’, decl_region(frame_region(‘_iterator::operator+’,
index: 3, depth: 4), ‘int * const’, ‘’))

 new equiv_class 
region_svalue(‘struct _iterator *’, decl_region(frame_region(‘Vector::Filter’,
index: 2, depth: 3), ‘struct _iterator’, ‘’))

 new equiv_class 
binop_svalue (pointer_plus_expr, unaryop_svalue (nop_expr, conjured_svalue (,
_iterator::_iterator (&__position, 0);,
decl_region(frame_region(‘Vector::Filter’, index: 2, depth: 3), ‘struct
iterator’, ‘iterator __position’))), constant_svalue(‘long unsigned int’, 4))

 new equiv_class 
sub_svalue (, conjured_svalue (, _iterator::_iterator (&__position, 0);,
decl_region(globals, ‘struct Vector’, ‘Vector vec’)),
cast_region(field_region(decl_region(globals, ‘struct Vector’, ‘Vector vec’),
‘int *’, ‘int* Vector::_M_finish’), ‘int * const’))

 new equiv_class 
binop_svalue (pointer_plus_expr, sub_svalue (, conjured_svalue (,
_iterator::_iterator (&__position, 0);, decl_region(globals, ‘struct Vector’,
‘Vector vec’)), field_region(decl_region(globals, ‘struct Vector’, ‘Vector
vec’), ‘int *’, ‘int* Vector::_M_finish’)), constant_svalue(‘sizetype’,
18446744073709551612))

[Bug analyzer/109027] [13 Regression] ICE: SIGSEGV (infinite recursion in ana::constraint_manager::eval_condition / ana::constraint_manager::impossible_derived_conditions_p) with -fanalyzer since r13-

2023-04-14 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109027

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #2 from Steven Sun  ---
Created attachment 54862
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54862=edit
new test case

New logic introduced in r13-6101-g4d3b7be281e73ecd causes infinite recursions.
Specifically, `impossible_derived_conditions_p` will fail to escape this
recursion.

In this situation, for some `a`, `b`, we have `a+4` and `b-4` exist in
different equivalent classes (of the `m_equiv_classes`).


Then we try to compare `a == b-4`, `impossible_derived_conditions_p` then bring
us to

to check`a == b-4`,
we'll look at   `b == a+4`,
since `a+4` is already in some equivalent class, we must know something about
it.


to check  `b == a+4`,
we'll look at `a == b-4`,
since `b-4` is already in some equivalent class, we must know something about
it.

Then, it continues infinitely. We should bail this out. Also, it seems that the
analyzer cannot recognize some template patterns, failing to enter any exit
paths.

This code path executes very rarely.

--

While trying to simplify the original test case, I discovered my new test case
is another infinite recursion but in a different code path.

[Bug analyzer/108767] O2 optimization has side effects on static analysis.

2023-04-10 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108767

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #2 from Steven Sun  ---
Like I just mentioned in #109190, you can check what is eaten by the analyzer.

https://godbolt.org/z/Yqd11hGM6

the `for (d = 0; d <= 1; ++d)` was optimized as  `for (d = 0; d != 2; ++d)`

It looks like it will increase the range of `d` to `d != 2`.

[Bug analyzer/109190] GCC Static Analyzer cannot handle the initialization of an array with a for loop

2023-04-10 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109190

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #4 from Steven Sun  ---
The analyzer is implemented as a ipa pass, which eats codes partially optimized
by the middle end, or the optimizer.

Your code presented to the analyzer looks like this in -O1

https://godbolt.org/z/KdaKW5Yae
```
int main ()
{
  int j;
  goto ; [100.00%]
   [local count: 536870913]:
  j_4 = j_1 + 1;
   [local count: 1073741824]:
  if (j_1 <= 0)
goto ; [50.00%]
  else
goto ; [50.00%]
   [local count: 536870913]:
  return 0;
}
```

And it looks like this in -O2
https://godbolt.org/z/rrjdaM4WP

```
int main ()
{
  MEM[(int *)0B] = 1;
  return 0;
}
```

The analyzer outputs should be definitely different.

I am not here to what causes this, but in case you're interested, you can use
godbolt to check all optimize passes.

[Bug c++/109283] Destructor of co_yield conditional argument called twice

2023-03-29 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109283

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #1 from Steven Sun  ---
It is indeed a bug. I currently only investigated into the gcc-12, it generates
something for

```
struct S{ /**/ };
bool w;

co_yield w ? S{"a"} : S{"b"};

```

pseudo-code for the generated gimple:

```
char __res[sizeof(S)];
char __a[sizeof(S)];
char __b[sizeof(S)];

new (__a) S("a");
new (__b) S("b");

if (w)
memcpy(__res, __a, sizeof(S));
else
memcpy(__res, __b, sizeof(S));

/*

...

*/

__b->~S();
__a->~S();
__c->~S();

```

So, clearly there is at least 3 bugs here:
i.   `__res` is never constructed.
ii.  only one of the `__a` and `__b` should be constructed, not both.
iii. the assignment is not corrected (it uses `gimple_assign` for value copy). 

If the ii is correctly implemented, iii will not happen.

Though, the code will work fine on all trivial types.

The correct code should be

```
char __res[sizeof(S)];

if (w)
new (__res) S("a");
else
new (__res) S("b");

/*

...

*/

__res->~S();

```

[Bug c++/108218] [12/13 Regression] Constant arguments in the new expression is not checked in unevaluated operand since r12-5253-g4df7f8c79835d569

2023-01-21 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108218

--- Comment #11 from Steven Sun  ---
(In reply to Andrew Pinski from comment #10)
> https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2392
> 
> "potentially-evaluated".

Oh, I realized that,

According to the DR 2392 accepted as a DR at the November, 2022 meeting:

https://cplusplus.github.io/CWG/issues/2392.html

We should not evaluate that expression in the first dimension of `new` anymore.
So this is not a bug.

This also applys for expressions appearing in requirement-seq of
requires-expressions.

So surprising! (Correct me if I am wrong)

[Bug c++/108218] [12/13 Regression] Constant arguments in the new expression is not checked in unevaluated operand

2022-12-24 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108218

--- Comment #7 from Steven Sun  ---
I got one simple idea as a workaround. I do not have the resources to do the
tests.

I agree anyone to take the following patch or the idea.


>From 35b4186a0ed3671de603bed6df5fb1156f087581 Mon Sep 17 00:00:00 2001
From: Steven Sun 
Date: Sun, 25 Dec 2022 06:44:43 +0800
Subject: [PATCH] c++: escape unevaluated context in new-expression

---
 gcc/cp/init.cc | 5 +
 1 file changed, 5 insertions(+)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index b49a7ca9169..974ea95959e 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -3929,7 +3929,12 @@ build_new (location_t loc, vec **placement,
tree type,
   /* Try to determine the constant value only for the purposes
 of the diagnostic below but continue to use the original
 value and handle const folding later.  */
+  /* Escape the possible unevaluated context. Constant folding does
+   not work in unevaluated context, but is required in nelts.  */
+  int old_cp_unevaluated_operand = cp_unevaluated_operand;
+  cp_unevaluated_operand = false;
   const_tree cst_nelts = fold_non_dependent_expr (nelts, complain);
+  cp_unevaluated_operand = old_cp_unevaluated_operand;

   /* The expression in a noptr-new-declarator is erroneous if it's of
 non-class type and its value before converting to std::size_t is
-- 
2.34.1

[Bug c++/108218] [12/13 Regression] Constant arguments in the new expression is not checked in unevaluated operand

2022-12-24 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108218

--- Comment #6 from Steven Sun  ---
g:4df7f8c79835d56928f51f9e674d326300936e8e

c++: don't do constexpr folding in unevaluated context

The implicit constexpr patch revealed that we were doing constant evaluation
of arbitrary expressions in unevaluated contexts, leading to failure when we
tried to evaluate e.g. a call to declval.  This is wrong more generally;
only manifestly-constant-evaluated expressions should be evaluated within
an unevaluated operand.

Making this change revealed a case we were failing to mark as manifestly
constant-evaluated.

gcc/cp/ChangeLog:

* constexpr.c (maybe_constant_value): Don't evaluate
in an unevaluated operand unless manifestly const-evaluated.
(fold_non_dependent_expr_template): Likewise.
* decl.c (compute_array_index_type_loc): This context is
manifestly constant-evaluated.

[Bug c++/108218] [12/13 Regression] Constant arguments in the new expression is not checked in unevaluated operand

2022-12-24 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108218

--- Comment #5 from Steven Sun  ---
h:4df7f8c79835d56928f51f9e674d326300936e8e

sorry, copied wrong hash code

[Bug c++/108218] [12/13 Regression] Constant arguments in the new expression is not checked in unevaluated operand

2022-12-24 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108218

--- Comment #3 from Steven Sun  ---
Bisecting tells me:

2551cd4f9bc1afee444a56e03c1cee6899593da9 is bad
adcfd2c45c3523d74279b5fcac1d7c6c34dd1382 is good



I think commit ddd25bd1a7c8f456bc914e34b77d43f39a1062d4 might be the root
cause.

[Bug c++/108218] [12 Regression] Constant arguments in the new expression is not checked in unevaluated operand

2022-12-24 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108218

--- Comment #1 from Steven Sun  ---
My concern is that, expressions within the require expressions are also
considered as "unevaluated operands".

Thus, the following concept is evaluated as true, but the program is ill-formed
and does not compile (since gcc 12)


https://godbolt.org/z/bcc398chG
```
template
concept C = requires
{
new int[(int)sizeof(T) - 4];
};

template requires C
class CC {
CC() {
new int[(int)sizeof(T) - 4];
}
};

template class CC;

```



: In instantiation of 'CC::CC() [with T = char]':
:16:16:   required from here
:12:32: error: size '-3' of array is negative
   12 | new int[(int)sizeof(T) - 4];
  | ~~~^~~

[Bug c++/108218] New: [12 Regression] Constant arguments in the new expression is not checked in unevaluated operand

2022-12-24 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108218

Bug ID: 108218
   Summary: [12 Regression] Constant arguments in the new
expression is not checked in unevaluated operand
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: StevenSun2021 at hotmail dot com
  Target Milestone: ---

```
int main() {
decltype(new int[-1]) a; // compiles with g++-12! <- regression here
 // does not compile with g++-11


auto b = new int[-1];// does not compile with g++-12
 // does not compile with g++-11
}
```
https://godbolt.org/z/aMGMrbfrd


expected behavior:
if, after conversion to std::size_t, the first dimension is a core constant
expression and it is potentially evaluated, the program is ill-formed.
https://en.cppreference.com/w/cpp/language/new

gcc(<=11.3 (current version)) and clang(>=3) does this check.

[Bug c++/101681] PMF comparison to nullptr is not considered a constexpr

2021-08-06 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101681

--- Comment #3 from Steven Sun  ---
By the way, in the current design, the class definition is passed twice in
order we can see every member data/function declaration before parsing NSDMI
and member functions.

The class is complete after parsing all declaration, which means `::f ==
nullptr` can reduce to false since that.

So, under current design, the following code compiles on GCC.
https://godbolt.org/z/fMTsf4KoM

```
struct C {
  C() {
static_assert(::f != 0);  // complete type
  }
  void f() noexcept(::f != 0) {
static_assert(::f != 0);  // complete type
  }
  static_assert(__builtin_constant_p(::f));// incomplete type
  static_assert(!__builtin_constant_p(::f == 0));  // incomplete type
};

static_assert(::f != 0);  // complete type

```

[Bug c++/101681] PMF comparison to nullptr is not considered a constexpr

2021-08-06 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101681

--- Comment #2 from Steven Sun  ---
The root cause for this is that the compiler forbids constant folding when
involving PMF of an incomplete class.

https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/cp/expr.c;h=d16d1896f2ddd08264b389b02b9640cca332ec13;hb=refs/heads/master#l42

(gcc/cp/expr.c)
> 42   /* We can't lower this until the class is complete.  */
> 43 if (!COMPLETE_TYPE_P (DECL_CONTEXT (member)))
> 44   return cst;


If we comment this `if`, the constant folding will succeed at


(gcc/cp/expr.c)
> 67 expand_ptrmemfunc_cst (cst, , );
> 68 cst = build_ptrmemfunc1 (type, delta, pfn);


solving everything.

[Bug c++/101681] PMF comparison to nullptr is not considered a constexpr

2021-08-06 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101681

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #1 from Steven Sun  ---
The following program compiles. https://godbolt.org/z/aTvchYxYW

```
struct C {
  void f() {}
  static_assert(__builtin_constant_p(::f));
  static_assert(!__builtin_constant_p(::f == nullptr)); // not nonzero yet
};

static_assert(__builtin_constant_p(::f == nullptr)); // nonzero now

struct D {
  void f() {}
  static_assert(__builtin_constant_p(::f == nullptr));
  static_assert(!__builtin_constant_p(::f == nullptr));
};

static_assert(__builtin_constant_p(::f == nullptr));
static_assert(__builtin_constant_p(::f == nullptr));

```


Looks that the `::f` is known to be constexpr right after the function was
parsed.

But only when the class completely parsed, its value was assigned. We can then
compare it to nullptr.


To make code in comment0 accepted, we need some kind of `not null' mark on the
expression tree. 0ne possible way is to assign the `::f` in advance, right
after it was parsed.

[Bug c++/101717] [12 Regression] ICE capturing static member within stateless generic lambda

2021-08-03 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101717

--- Comment #5 from Steven Sun  ---
(In reply to Andrew Pinski from comment #4)
Thanks!


(In reply to myself from comment #3)

> The program seems never think of a situation "a lambda inside a lambda
> inside a NSDMI`. We need to amend the logic here.


edit to:

The program seems never think of a situation "member function call inside a
generic lambda inside a lambda inside a NSDMI`. We need to amend the logic
here.


-

The direct cause of failure is in g:91e534b0d

```
if (!containing_function && !COMPLETE_TYPE_P (closure))
/* If we're parsing a lambda in a non-local class,
   we can find the fake 'this' in scope_chain.  */
init = scope_chain->x_current_class_ptr;
```

This part of logic is to find the potential `this` since there is a (static)
member function call `f`. Refer to the following comments:

  /* For the overload resolution we need to find the actual `this`
 that would be captured if the call turns out to be to a
 non-static member function.  Do not actually capture it at this
 point.  */


// in function `build_new_method_call_1` in `gcc/cp/call.c`

-

As for example in comment 1:


`scope_chain->x_current_class_ptr` is correctly set when parsing 

```
[=](auto) { f(); }
```

But it was soon incorrectly set when instantiating the same lambda, i.e.
parsing

```
[=](auto) { f(); }()
``` 


This failure only affectes the potential `this` pointer inside the

```
[=](auto) { f(); }
```

But since here needs no `this` pointer, deleting that problematical
`gcc_checking_assert` is actually a potential fix for this problem.

[Bug c++/101717] [12 Regression] ICE capturing static member within stateless generic lambda

2021-08-03 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101717

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #3 from Steven Sun  ---
This bug is not introduced in GCC 12.

The relevant code fragment is last edited by g:91e534b0d


in `gcc/cp/lambda.c`
```
gcc_checking_assert
(init && (TREE_TYPE (TREE_TYPE (init))
== current_nonlambda_class_type ()));

```

The assertion fails since long ago. (init == 0 in this case)

Before GCC 12, the `gcc_checking_assert` is `(void)0` in release version,
leaving everything fine. Somehow `gcc_checking_assert` starts working now, and
aborts the program.


My insight on the problem:
The program seems never think of a situation "a lambda inside a lambda inside a
NSDMI`. We need to amend the logic here.

"here" means
https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/cp/lambda.c;h=2e9d38bbe832702804ddcaffc4024ce930a74843;hb=refs/heads/master#l755

By the way, does anyone know other magics like g:hash?

[Bug c++/100877] g++ freezes system by consuming infinite amount of memory

2021-06-02 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100877

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #2 from Steven Sun  ---
Feng use a non-exist member in your definition of 

 template< Expression Ex, Place_Holder Ph, Expression Ey >
  auto replace_placeholder_with_expression( Ex const& ex, Ph const&
old_place_holder, Ey const& new_expression )


namely `ex.reset_action_`. It the one and only bug in your code. It compiles in
a few seconds after being fixed.

CONCLUSION: No bug in GCC but a stupid bug in Feng's code.


But interestingly, GCC eats so much memory to dump an error message involving
lambdas, template lambdas, and templates (eats 20G in my desktop, >400G in
Feng's cluster).

[Bug c++/100877] g++ freezes system by consuming infinite amount of memory

2021-06-02 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100877

--- Comment #1 from Steven Sun  ---
I look at the call stack. Most of the time is wasted on `dump_template_parms`
in `gcc/cp/error.c`. I commented several functions calling it:

(I'm using stage-1 compiler)

`announce_function` in `gcc/toplev.c`
`push_tinst_level_loc` in `gcc/cp/pt.c`
`cp_printer` in `gcc/cp/error.c` (directly return true)

Then I got the output after a few seconds.

--
examples/../include/./model.hpp: In instantiation of ‘’:
examples/../include/./model.hpp:55:147:   required from ‘’
examples/../include/./model.hpp:61:77:   required from ‘’
examples/../include/./model.hpp:55:147:   [ skipping 8 instantiation contexts,
use -ftemplate-backtrace-limit=0 to disable ]
examples/../include/./model.hpp:55:147:   required from ‘’
examples/../include/./model.hpp:55:147:   recursively required from ‘’
examples/../include/./model.hpp:55:147:   required from ‘’
examples/../include/./model.hpp:60:77:   required from ‘’
examples/../include/./model.hpp:60:77:   recursively required from ‘’
examples/../include/./model.hpp:55:147:   recursively required from ‘’
examples/../include/./model.hpp:55:147:   required from ‘’
examples/../include/./model.hpp:55:147:   recursively required from ‘’
examples/../include/./model.hpp:55:147:   required from ‘’
examples/../include/./model.hpp:60:77:   required from ‘’
examples/../include/./model.hpp:55:147:   required from ‘’
examples/../include/./model.hpp:382:55:   required from ‘’
examples/dcgan.cc:48:43:   required from here
examples/../include/./model.hpp:59:96: error: ‘’ has no member named ‘’
--

But I cannot give the output. Because the dumping process will lead to an out
of memory.



If I disable member access check, it gives an error
-
examples/../include/./model.hpp: In instantiation of ‘’:
examples/../include/./model.hpp:55:147:   recursively required from ‘’
examples/../include/./model.hpp:55:147:   required from ‘’
examples/../include/./model.hpp:60:77:   required from ‘’
examples/../include/./model.hpp:55:147:   required from ‘’
examples/../include/./model.hpp:382:55:   required from ‘’
examples/dcgan.cc:48:43:   required from here
examples/../include/./model.hpp:60:77: error: use of ‘’ before deduction of
‘auto’

It's the same source location!

and it is in your definition of 

 template< Expression Ex, Place_Holder Ph, Expression Ey >
  auto replace_placeholder_with_expression( Ex const& ex, Ph const&
old_place_holder, Ey const& new_expression )


[Bug c++/99686] ICE when using both concepts and full specialization

2021-05-07 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686

--- Comment #8 from Steven Sun  ---
under c++17

Step 4 needs `types_match == 1` [at 1] but, its value is zero, which is caused
by `function_requirements_equivalent_p` [at 3] returns 0 [at 2] .

[1]
https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/cp/decl.c;h=316ad4c1426940bd4f51197a6297eefc24064fec;hb=HEAD#l1481
[2]
https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/cp/decl.c;h=316ad4c1426940bd4f51197a6297eefc24064fec;hb=HEAD#l1052
[3]
https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/cp/decl.c;h=316ad4c1426940bd4f51197a6297eefc24064fec;hb=HEAD#l944
[4]
https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/cp/pt.c;h=36a8cb5df5d36337c18e1547e775b747f59a087f;hb=HEAD#l3510

In `function_requirements_equivalent_p` [at 3], the comparison is different for
cxx20 and before.

According to the comments, before c++20, only the combined constraints are
compaired.

--
By the way, for those two primary function templates in comment 1. Before
cxx20, they are regard as 

equivalent heads [at 4]
inequivalent requirements [at 3]

Since cxx20, they are regard as 

inequivalent heads [at 4]
equivalent requirements [at 3]

If I change both [3], [4], forcing cxx17 using cxx20 standard, everything
works.
-
Many invariants are broken here. They cause this bug together:

A failure in requirements comparison caused no reregistration, which leads to
overload between implicit instatntiation. The full specialzation is already
parsed, leaving a null `cfun` state. Then it tries to instatiate the function
body and everything crashes,

They are all `by design` in a sense. How to fix it is not only a technical
issue, but a design choice.

If any senior gcc developer sees this, help me.
-
By the way, I don't think this bug would matter too much, since no one really
uses concepts before c++20. I am just curious.

[Bug c++/99686] ICE when using both concepts and full specialization

2021-05-07 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686

--- Comment #7 from Steven Sun  ---
After digging for two days, I think I may know what's happening inside. 

Under std=c++20 and my code in comment 1, the flow when parsing a full function
specialization would be

1. Found a full specialization of function.
2. Instantiate all possible primary function templates. 
3. Find the most suitable instantiation (here, the concept constrained is
chosen)
4. Then replace it with full specialization. (this is done in
`reregister_specialization` in `gcc/cp/pt.c`)

So when performing overloading in the main function, there would be one
instantiation and one full specialization to choose. (To be specific, those two
are in the hash table `decl_specialization` defined in `gcc/cp/pt.c`)


While in the c++17 mode, step 4 is broken. So there will be 2 implicit
instantiation to choose when overloading.

Step 4 is performed in the function `duplicate_decls` defined in
`gcc/cp/decl.c`.

Certain conditions must be satisfied to replace the instantiation.

The one failed here is:
"the compiler thinks the full specialization has a different concepts
constraint with primary template (because the primary template has contraints
but the full specialization doesn't)" 

So the reregistration is never triggered. This is the source of the bug.

After getting the whole picture, I simplify the test case as
https://godbolt.org/z/9MM6rEf77

--- std=c++17 -fconcepts

template 
requires requires(T t) { ++t; }
void func(T &)
{
}

template <>
void func(int&& arg)
{
}

int main()
{
func(1);
}

---

I'll give more details in the next comment in case any developer would like to
fix it.

[Bug c++/99686] ICE when using both concepts and full specialization

2021-05-04 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686

--- Comment #6 from Steven Sun  ---
While in C++20, the complier thinks it's unnecessary to instatiate a new
template. Just use the full specialization! Thus, this bug wouldn't exist at
first place.

Intuitively, I am in favor of the compiler's C++20 behavior -- use full
specialization anyway.

Clang 12 and MSVC latest also have this behavior (choose full specialization).


I don't know how to contribute to gcc. If anyone would like to fix this bug, my
recommendation would be:

Make the compiler in C++17 mode think it's unnecessary to instantiate a new
function when full specialzation is provided, which resulting the same behavior
as C++20 mode and as other compilers.

[Bug c++/99686] ICE when using both concepts and full specialization

2021-05-04 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686

--- Comment #5 from Steven Sun  ---
I learn a little about gcc recently. I think I got a vague idea of what's going
on inside.

In c++17 mode with concepts, and with my code in comment 1.

The compiler decides to instantiate from the concept constrained template.



Usually the compiler should generate a new function on the AST, but this time
there's already one function (fully specialized) on the AST.

So, the function `start_preparsed_function` in the below link returns at the
quoted line. It's thinking "Ah! There's already a function, no need to allocate
a new one."

https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/cp/decl.c;h=316ad4c1426940bd4f51197a6297eefc24064fec;hb=HEAD#l16696



Then the flow goes back to the function in the link below. It's thinking "Since
I'm gonna add a new function, new function is allocated on AST. Everything
should be prepared for me!"

More specifially, it will assume the `cfun` in the correct state set by the
`start_preparsed_function`.

But `cfun` is null, since the `start_preparsed_function` returns early. This is
the direct cause of segfault, which triggered at the line below.

https://gcc.gnu.org/git?p=gcc.git;a=blob;f=gcc/cp/pt.c;h=36a8cb5df5d36337c18e1547e775b747f59a087f;hb=HEAD#l25932



In conclusion, The compiler doesn't consider there would be a situation that an
instatiation is still needed when full specialzation is provided. This break
the invariants.

[Bug c++/99686] ICE when using both concepts and full specialization

2021-03-25 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686

--- Comment #3 from Steven Sun  ---
@W E Brown: I got your idea. So are all uses like this ill-formed? This seems
unexpected for me. I would expect the complete specialization is full
specialization for both primary templates.

I also find facts that support your idea:

If I modify the full specialization to 

template <>
void func (int&& arg){}

It compiles. See https://godbolt.org/z/fh9Mx7Krr


If I modify the full specialization to 

template <>
void func (int&& arg){}

It produce the same ICE output as comment 1. See
https://godbolt.org/z/eMa5YcrrE

It looks like the compiler doesn't knows which primary template to specialize.

I look up in the C++20 standard, and did not find anything about 2 primary
templates exists.

The code in Comment 1 compiles for g++ 6.1 to 9.3, then breaks since 10.1 (all
under -std=c++17 -fconcepts).

In conclusion, this makes sences but I didn't see that coming. Anyway, I think
a possible improvement is make ICE to an error of "ambigous full
specialization". Or even better, a change in C++23 standard.

[Bug c++/99686] ICE when concepts on C++17 when providing both T&& and const T& specialization

2021-03-20 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686

--- Comment #1 from Steven Sun  ---
The compiler args are only "g++ -fconcepts -std=c++17"

It should choose the full specialization func(int &&), while the compiler
aborts during the instatiation of the partial specialization (using concepts).

If either the partial or the full specialzation is removed, it compiles.


New online compiler link: https://godbolt.org/z/fK5G61
-
template 
void func(T &)
{
}

template 
requires requires(T t) { ++t; }
void func(T &)
{
}

template <>
void func(int &)
{
}

int main()
{
func(1); // I am expecting func(int&&)
}
-

Error:
In instantiation of ‘void func(T&&) [with T = int]’:
internal compiler error: Segmentation fault
   11 | }
  | ^
Please submit a full bug report,

[Bug c++/99686] New: ICE when concepts on C++17 when providing both T&& and const T& specialization

2021-03-20 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686

Bug ID: 99686
   Summary: ICE when concepts on C++17 when providing both T&& and
const T& specialization
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: StevenSun2021 at hotmail dot com
  Target Milestone: ---

This problem occurs only when using std=c++17 and -fconcepts. It compiles when
using std=c++20.


I also have an online compiler link for this. https://godbolt.org/z/W9r6Wx

-
template 
void func(T &)
{
}

template 
requires requires(T t) { ++t; }
void func(T &)
{
}

template <>
void func(int &)
{
}

template <>
void func(const int )
{
}

int main()
{
func(1); // I am expecting func(int&&)
}

[Bug c++/99019] New: A nicer error hint, for cpp modules, if missing headers

2021-02-09 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99019

Bug ID: 99019
   Summary: A nicer error hint, for cpp modules, if missing
headers
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: StevenSun2021 at hotmail dot com
  Target Milestone: ---

This is not a bug but can be improved.

If I forget to include headers, like the following
---
export module B;

export void foo()
{
std::cout << 1;
}
---

Compile it with g++ 11, I get an error hint:
---
test.cpp: In function ‘void foo()’:
test.cpp:5:10: error: ‘cout’ is not a member of ‘std’
5 | std::cout << 1;
  |  ^~~~
test.cpp:1:1: note: ‘std::cout’ is defined in header ‘’; did you
forget to ‘#include ’?
  +++ |+#include 
1 | export module B;
---

Actually it should be 

  +++ |+module;
  +++ |+#include 
1 | export module B;



Using a build of brunch devel/c++-modules. Built 3 days ago.

[Bug c++/98944] [modules] Failed to read compiled module with a non-exported partition.

2021-02-08 Thread StevenSun2021 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98944

Steven Sun  changed:

   What|Removed |Added

 CC||StevenSun2021 at hotmail dot 
com

--- Comment #1 from Steven Sun  ---
I met the same problem. 

-

Three days ago, I pull from the repository and then compile the gnu c++
compiler in the devel/c++-modules branch.

system: ubuntu-20.04 x86_64
configured with: --disable-multilib

I took the same exaple as you, which is in the final working draft n4861
[modules.unit].

I think the compile order should be tu3 tu2 tu1 tu4, because the compiler tells
me I cannot import before build. So I compile it as 


g++ -fmodules-ts -std=c++20 -c 3.cc -o 3.o
g++ -fmodules-ts -std=c++20 -c 2.cc -o 2.o
g++ -fmodules-ts -std=c++20 -c 1.cc -o 1.o
g++ -fmodules-ts -std=c++20 -c 4.cc -o 4.o


The compiling for 4.cc got an error
--
In module imported at 4.cc:1:1:
A: error: failed to read compiled module: Bad file data
A: note: compiled module file is ‘gcm.cache/A.gcm’
A: fatal error: returning to the gate for a mechanical issue
compilation terminated.
--

Then I took a peek into the gcm.cache/A.gcm, using readelf. Found that there's
already a section header named bar.

So I removed the line `import :Internals;` in 4.cc and it compiles.

Anyway, I don't know if that is a bug. Maybe the standard is different from the
final working draft. I am not sure.