hollinsky added a comment.

This change breaks return value deduction of template instantiations that first 
occur within a discarded context.

  template<int S>
  class Foo {
  public:
        constexpr Foo(const char str[S]) : buf(str[0]) {}
        char get() const { return buf; }
        char buf;
  };
  
  template<int S>
  static constexpr auto make(const char(&str)[S]) {
        return Foo<S>{str};
  }
  
  int main() {
        if constexpr(false) {
                return make("used to be Foo<29>, now void").get();
        }
        return 0;
  }

This code now fails to compile with

  regression.cpp:16:46: error: member reference base type 'void' is not a 
structure or union
                  return make("used to be Foo<29>, now void").get();
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~

The only return statement in the `make()` function template is not being 
considered anymore, making the resulting instantiation

  template<>
  static constexpr void make(const char(&str)[29]) {
        return Foo<29>{str};
  }

Intuitively, I wouldn't think that the "discarded return statements are not 
considered when deducing a return type" rule should continue into new function 
scopes, though I'm not sure exactly how the spec backs that up.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113749/new/

https://reviews.llvm.org/D113749

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to