LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 39663 - Class template argument deduction with deduced type fails when accessing member
Summary: Class template argument deduction with deduced type fails when accessing member
Status: RESOLVED DUPLICATE of bug 47175
Alias: None
Product: clang
Classification: Unclassified
Component: C++17 (show other bugs)
Version: 7.0
Hardware: PC All
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-11-14 11:58 PST by Baruch
Modified: 2020-10-15 17:45 PDT (History)
10 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Baruch 2018-11-14 11:58:06 PST
Try to compile the following c++ program:

  template <class T>
  struct C {
    C(T) {}
    int a;
  };

  template <class T>
  int foo(T v) {
    return C{v}.a; // <----
  }

  int main() {
    foo(4);
  }

The line marked above fails with the error:

error: member reference base type 'C' is not a structure or union
    return (C{v}).a;
           ~~~~~~^~

Note that the following all work fine:

  template <class T>
  C<T> foo(T v) {
    return C{v};
  }

and

  int foo(int v) {
    return C{v}.a;
  }

and

  C{4}.a;

I tried this also on a recent trunk build (trunk 346600)
Comment 1 Baruch 2018-11-14 12:07:55 PST
Sorry, for the last example of what works I meant:

  template <class T>
  int foo(T v) {
    return C{4}.a;
  }
Comment 2 Richard Smith 2018-11-14 12:59:12 PST
Confirmed, presumably we are incorrectly concluding that the dependent non-deduced type `C` cannot possibly be a class type.
Comment 3 Dalton Woodard 2019-09-10 15:54:23 PDT
A coworker of mine just came across the same issue. I have another set of repros and a few cases that do work as expected. I've tested and reproduced the same error back to Clang 5.0 and through until trunk as of today. Interestingly enough it occurs during parsing and not during template instantiation.

  template <class T>
  struct S
  {
      S(T t) : t(t) {}
      T t;
  };

  template <class T>
  void good1(T v)
  {
      (void)S(v);
  }

  template <class T>
  void good2(T v)
  {
      auto s = S(v);
      (void)s.t;
  }

  void good3()
  {
      (void)[](int v) { (void)S(v).t; };
  }

  void good4()
  {
      (void)S(42).t;
  }

  void good5()
  {
      (void)[](auto) { (void)S(42).t; };
  }

  template <class T>
  void bad1(T v)
  {
      // fails with:
      // error: member reference base type 'S' is not a structure or union
      (void)S(v).t;
  }

  void bad2()
  {
      // fails with:
      // error: member reference base type 'S' is not a structure or union
      (void)[](auto v) { (void)S(v).t; };
  }
Comment 4 Erich Keane 2020-10-12 19:56:57 PDT
Looks like this has been fixed? The repro at least no longer does in Trunk: https://godbolt.org/z/jofz6e
Comment 5 Richard Smith 2020-10-15 17:45:44 PDT
Yes, fixed under duplicate PR47175.

*** This bug has been marked as a duplicate of bug 47175 ***