Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clang parser crashes on decomposing a structured binding to a templated aggregate-like class #38496

Closed
mrks opened this issue Oct 2, 2018 · 11 comments
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@mrks
Copy link
Member

mrks commented Oct 2, 2018

Bugzilla Link 39148
Resolution FIXED
Resolved on Jan 31, 2019 07:53
Version trunk
OS All
Blocks #39678
CC @efriedma-quic,@orivej,@zygoloid,@tstellar
Fixed by commit(s) 352323, 352356

Extended Description

The attached six lines kill clang 7 under OS X 10.14 as well as clang trunk under godbolt: https://godbolt.org/z/vnPguy

Excerpt from error message:

  1. clangbug.cpp:6:45: current parser token '{'
  2. clangbug.cpp:5:12: parsing function body 'main'
  3. clangbug.cpp:5:12: in compound statement ('{}')
    [...]
    4 clang-7 0x0000000106cd42db clang::Sema::CheckCompleteVariableDeclaration(clang::VarDecl*) + 1555
    5 clang-7 0x0000000106cd3629 clang::Sema::AddInitializerToDecl(clang::Decl*, clang::Expr*, bool) + 3471
    6 clang-7 0x0000000106ef38c8 clang::Sema::BuildCXXForRangeStmt(clang::SourceLocation, clang::SourceLocation, clang::SourceLocation, clang::Stmt*, clang::Stmt*, clang::Stmt*, clang::Expr*, clang::Expr*, clang::Stmt*, clang::SourceLocation, clang::Sema::BuildForRangeKind) + 5526
    [...]
    clang-7: error: unable to execute command: Segmentation fault: 11
@orivej
Copy link
Contributor

orivej commented Oct 19, 2018

This bug is present in clang 6, 5 and 4 (that requires -std=c++1z for c++17), so it does not block the release of 7.0.1.

@zygoloid
Copy link
Mannequin

zygoloid mannequin commented Oct 19, 2018

Do you by any chance have a reduced testcase that doesn't depend on boost?

@orivej
Copy link
Contributor

orivej commented Oct 19, 2018

This one is difficult to reduce until llvm/llvm-bugzilla-archive#39311 is fixed because it is easy to trigger the latter, but I'm trying.

@orivej
Copy link
Contributor

orivej commented Oct 20, 2018

I have reduced it (tested with "clang++ -c -std=c++17 test.cpp"):

 struct A;
 struct Iter { A& operator*(); void operator++(); };
 bool operator!=(Iter, Iter);
 struct { Iter begin(); Iter end(); } seq;
 void f() { for (auto& [left, right] : seq); }

@orivej
Copy link
Contributor

orivej commented Oct 20, 2018

The previous example is expected to fail: g++ 8.2.0 prints "error: structured binding refers to incomplete type 'A'". Here is an example that is expected to succeed (g++ 8.2.0 compiles it):

 template <int> struct Pair { int left, right; };
 struct Iter { Pair<0>& operator*(); void operator++(); };
 bool operator!=(Iter, Iter);
 struct Seq: public Iter { Seq begin(); Seq end(); };
 void f(Seq seq) { for (auto& [left, right] : seq); }

@orivej
Copy link
Contributor

orivej commented Oct 20, 2018

A bit simpler:

 template <class T> struct Pair { T left, right; };
 struct Iter { Pair<int>& operator*(); void operator++(); };
 bool operator!=(Iter, Iter);
 struct Seq { Iter begin(); Iter end(); };
 void f(Seq seq) { for (auto& [left, right] : seq) {}; }

@orivej
Copy link
Contributor

orivej commented Oct 20, 2018

The loop is not necessary; this also crashes clang:

 template <class T> struct A { T x; };
 void f(A<int>& a) { auto& [x] = a; }

@orivej
Copy link
Contributor

orivej commented Nov 20, 2018

I'd bump the priority to release blocker (w.r.t. Clang 8) because the crash on a valid C++ 17 input makes it the case of not supporting the standard.

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 14, 2018

The loop is not necessary; this also crashes clang:

 template <class T> struct A { T x; };
 void f(A<int>& a) { auto& [x] = a; }

I examined combinations of qualifications by
https://pastebin.com/Cj58JM3L
and found that clang crashes when

  1. f is not a template function, while template<class T> void f(A<T>&); works; and
  2. both of the argument and the structured binding are reference-qualified as & or &&.

CV-qualification of them does not matter (as far as a code is well-formed).

So, clang also crashes with, e.g., void f(const A<int>& a) { auto&& [x] = a; }.

I tested on wandbox.org and clang 4.0.0–8.0.0 crashes (https://wandbox.org/permlink/euBUwdn06J1FrlWG).

I hope this helps.

Best.

@orivej
Copy link
Contributor

orivej commented Jan 31, 2019

Fixed in trunk in r352323 and in 8 in r352356 by https://reviews.llvm.org/D56974.

@zmodem
Copy link
Collaborator

zmodem commented Nov 27, 2021

mentioned in issue #39678

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
None yet
Development

No branches or pull requests

4 participants