[Bug c++/113405] Can't access member type alias of concept-constrained class template specialization in global module fragment via alias template in different module

2024-01-18 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113405

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #4 from Nathaniel Shead  ---
The issue seems to be that 'depset::hash::add_specializations' only adds the
first of a set of constrained specialisations that use the same arguments. This
comes down to the fact that the 'type_specializations' hashset is only hashed
on the base template and the provided arguments: differently constrained
specialisations just aren't added.

Other parts of the dependency walker seem to handle this OK, by walking the
DECL_TEMPLATE_SPECIALIZATIONS list, but not the base 'specialization_add'
function.

I'm not entirely sure yet what the best way to approach solving this is.

[Bug c++/113308] derived class doesn't currently allow inherited explicit object member function post increment operator

2024-01-10 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113308

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #1 from Nathaniel Shead  ---
I believe this is correct behaviour: The definition of `operator++` in the
child class hides the `operator++` declared in the base class. Similarly to the
following code:


struct base {
  void f(int) {}
};
struct d1 : base {
  void f() {}
};
struct d2 : base {
  using base::f;  // explicitly add base::f as an overload
  void f() {}
};

int main() {
  d1{}.f(10);  // error
  d2{}.f(10);  // OK
}

[Bug c++/104221] member functions defined in separate files of classes declared in module partitions won't compile

2024-01-03 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104221

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #1 from Nathaniel Shead  ---
I think this is IFNDR; you cannot have more than one partition with the same
name. See https://eel.is/c++draft/module.unit#3:

> A module partition is a module unit whose module-declaration contains
> a module-partition. A named module shall not contain multiple module
> partitions with the same module-partition. All module partitions of a
> module that are module interface units shall be directly or indirectly
> exported by the primary module interface unit ([module.import]).
> No diagnostic is required for a violation of these rules.

And in particular, unlike a module implementation unit, a module partition does
not implicitly import anything; see https://eel.is/c++draft/module.unit#8 which
says:

> A module-declaration that contains neither an export-keyword nor a
> module-partition implicitly imports the primary module interface unit
> of the module as if by a module-import-declaration.

So this is working as specified. I don't think there'd be any good way of
improving the diagnostics for this either.

[Bug c++/113031] [14 Regression] ICE in cxx_fold_indirect_ref_1 starting with r14-6508

2023-12-21 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113031

--- Comment #6 from Nathaniel Shead  ---
Yes, fixed as far as I'm aware.

[Bug c++/113047] dereferencing a null pointer in a constant expression

2023-12-19 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113047

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #4 from Nathaniel Shead  ---
I've pushed a fix for PR102420 (and hence comment #1), but looking at the DR
this isn't sufficient for the result of CWG2823, for which presumably all of
the following should also start erroring as well (note none of these error in
Clang yet either):

  struct X {
static constexpr int f() { return 0; }
  };

  constexpr int g(X* x) { return (*x).f(); }  // error
  constexpr int a = g(nullptr);

  constexpr int h(X* x) { return x->f(); }  // error
  constexpr int b = h(nullptr);

  // and similarly
  constexpr int test() {
int* p = nullptr;
*p;  // error
return 0;
  }
  constexpr int t = test();

[Bug c++/113031] [14 Regression] ICE in cxx_fold_indirect_ref_1 starting with r14-6508

2023-12-15 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113031

--- Comment #2 from Nathaniel Shead  ---
Reduced to:


template  class variant;

template 
auto __variant_cast(_Tp __rhs) { return static_cast&&>(__rhs);
}

template 
struct _Move_assign_base : _Types {
  void operator=(_Move_assign_base __rhs) { __variant_cast<_Types>(__rhs); }
};

template 
struct variant : _Move_assign_base<_Types> {
  void emplace() {
variant __tmp;
*this = __tmp;
  }
};

struct _Undefined_class {
  struct _Nocopy_types {
void (_Undefined_class::*_M_member_pointer)();
  };
  struct function : _Nocopy_types {
struct optional {
  void test03() {
variant v;
v.emplace();
  }
};
  };
};


The following patch seems to fix the immediate problem (but not yet fully
regtested):

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index e1b2d27fc36..051f73fb73f 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -5709,7 +5709,8 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx,
location_t loc, tree type,
  }

   /* Handle conversion to "as base" type.  */
-  if (CLASSTYPE_AS_BASE (optype) == type)
+  if (CLASS_TYPE_P (optype)
+ && CLASSTYPE_AS_BASE (optype) == type)
return op;

   /* Handle conversion to an empty base class, which is represented with a

[Bug c++/112820] vtable not emitted correctly from module when compiling with -g

2023-12-02 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112820

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #1 from Nathaniel Shead  ---
The issue seems to be that the same flag is used for DECL_EXTERN and
TYPE_DECL_SUPPRESS_DEBUG, and the modules reading code is getting confused and
thinking that TYPE_DECLs with the latter flag set means that they are actually
DECL_EXTERN and thus preventing them from being emitted.

The following hunk fixes this issue but it'd probably be better to clean up all
handling of extern within the modules reading so that we don't lose the
"suppress debug" flag entirely.

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 33fcf396875..add3fa4b945 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -5397,7 +5397,7 @@ trees_out::core_bools (tree t)
   DECL_NOT_REALLY_EXTERN -> base.not_really_extern
 == that was a lie, it is here  */

-   bool is_external = t->decl_common.decl_flag_1;
+   bool is_external = code != TYPE_DECL && t->decl_common.decl_flag_1;
if (!is_external)
  /* decl_flag_1 is DECL_EXTERNAL. Things we emit here, might
 well be external from the POV of an importer.  */

[Bug c++/112588] ICE in make_decl_rtl when returning str literal when string header imported in module

2023-11-17 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112588

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #1 from Nathaniel Shead  ---
Minimised (the actual offender here is the with std::allocator):


  // test.h
  void f(int*);

  template 
  struct S {
void g(int n) { f(&n); }
  };

  template struct S;


  // a.cpp
  module;
  #include "test.h"
  export module test;


  // b.cpp
  #include "test.h"
  import test;


So far it seems the issue is that the PARM_DECL in the expression tree of the
body of the instantiation for `S::g` is a different node from the actual
PARM_DECL in g's DECL_ARGUMENTS; the latter gets RTL but the former does not.
The issue is in the deduplication logic for instantiations somewhere.

The following patch fixes this issue but causes other issues in the testsuite,
and I don't think this is the correct approach anyway:


diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 4f5b6e2747a..f2d191fc408 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -8302,9 +8302,7 @@ trees_in::decl_value ()
   if (TREE_CODE (inner) == FUNCTION_DECL)
{
  tree e_inner = STRIP_TEMPLATE (existing);
- for (auto parm = DECL_ARGUMENTS (inner);
-  parm; parm = DECL_CHAIN (parm))
-   DECL_CONTEXT (parm) = e_inner;
+ DECL_ARGUMENTS (inner) = DECL_ARGUMENTS (e_inner);
}

   /* And our result is the existing node.  */


(I was originally working on this after attempting to reduce PR9.)

[Bug c++/106851] [modules] Name conflict for exported using-declaration

2023-11-09 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106851

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #2 from Nathaniel Shead  ---
This behaviour should be as expected right? The 'using' is trying to bring both
names into the same scope (the global namespace), irrespective of the fact that
we're also exporting that new declaration. (That is, removing the 'export'
keywords from this test case gives the exact some result.)

That said, perhaps it would be helpful for the error message to point to the
using-declaration it actually conflicts with, rather than the definition that
said using-declaration points to.

[Bug c++/110936] if constexpr: member function pointers cannot be checked with ubsan

2023-11-08 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110936

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #3 from Nathaniel Shead  ---
More generally this appears to be caused by '-fno-delete-null-pointer-checks'
causing constant folding not to occur. Minimised example:

  struct foo { void bar() { } };
  constexpr bool b = &foo::bar;

https://gcc.godbolt.org/z/x7csTzjfa

[Bug c++/96090] noexcept operator of potentially-throwing defaulted function gives the wrong result

2023-10-28 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96090

Nathaniel Shead  changed:

   What|Removed |Added

 CC||nathanieloshead at gmail dot 
com

--- Comment #2 from Nathaniel Shead  ---
I'm working on a patch for this. But worth noting...

> static_assert(!is_nothrow_default_constructible_v);
I'm not sure this is correct. By https://eel.is/c++draft/meta.unary.prop#9 this
is testing noexceptness of value-initialisation. And
https://eel.is/c++draft/dcl.init.general#9.1 says

> if T has either no default constructor ([class.default.ctor]) or
>a default constructor that is user-provided or deleted, then
>the object is default-initialized;
> otherwise, the object is zero-initialized and the semantic constraints
>for default-initialization are checked, and if T has a non-trivial
>default constructor, the object is default-initialized;
Since the default constructor here is not user-provided, and also trivial, the
object should not be default-initialized and thus the default constructor is
not called, and thus this is not potentially-throwing.

[Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference

2023-10-25 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101631

--- Comment #6 from Nathaniel Shead  ---
(In reply to Sam James from comment #5)
> Fixed for 14 then by the drive-by bit or is there something left?
It should be fixed now. The example in comment #2 is
g++.dg/cpp2a/constexpr-union2.C.

[Bug c++/111226] New: constexpr doesn't detect change of union to empty member

2023-08-29 Thread nathanieloshead at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111226

Bug ID: 111226
   Summary: constexpr doesn't detect change of union to empty
member
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: nathanieloshead at gmail dot com
  Target Milestone: ---

While working on a patch for PR101631, I found that the following code is
currently incorrectly handled by GCC: (https://godbolt.org/z/1YevacMK3)


struct Empty {};

union U {
  int x;
  Empty e;
};

constexpr int foo() {
  U u{ 10 };
  u.e = {};
  return u.x;  // incorrectly accepted, even pre-C++20
}
constexpr auto y = foo();

constexpr Empty bar() {
  U u{ 10 };
  u.e = {};
  return u.e;  // incorrectly errors, thinks active member is still 'x'
}
constexpr auto x = bar();


The cause seems to be that the zero-sized trivial assignment is removed in
call.cc (since PR43075) and after constant folding is no longer in the tree
that the constexpr handling machinery receives.