Skip to content

[BUG] clang-cl compiler error with generated c++ code for swap member function with 'that' parameter #1423

Description

@inflooper

Describe the bug
Defining a swap member function with a that parameter causes compiler error with clang-cl. The code emitted by a swap member function with a that parameter looks like the following:

 public: auto swap(test&& that) noexcept && -> void;

The compiler is not happy with noexcept followed by &&. It only compiles when && precedes noexcept.

To Reproduce
Steps to reproduce the behavior:

  1. Sample code - distilled down to minimal essentials please
test: type = {
  a: int = 0;

  swap: (move this, move that) = {
  	temp_a: int = this.a;
  	a = that.a;
  	that.a = temp_a;
  }
}
  1. Command lines including which C++ compiler you are using
clang version 19.1.5
Target: x86_64-pc-windows-msvc
cppfront compiler v0.8.2 Build A828:0952

.\cppfront\bin\cppfront.exe .\member_func_rvalue_qualifier_bug.cpp2 -p
clang-cl .\member_func_rvalue_qualifier_bug.cpp -std:c++20 -EHsc -I .\cppfront\include\

  1. Expected result - what you expected to happen
    Either:
    A. The noexcept and && function qualifiers are swapped during code generation
    B. cppfront compiler error stating that is not allowed in swap function

  2. Actual result/error

.\member_func_rvalue_qualifier_bug.cpp2(4,41): error: expected ';' at end of declaration list
    4 |  public: auto swap(test&& that) noexcept && -> void;
      |                                         ^
      |                                         ;
.\member_func_rvalue_qualifier_bug.cpp2(4,40): error: expected function body after function declarator
    4 |  auto test::swap(test&& that) noexcept && -> void{
      |                                        ^

Additional context
cpp code emitted by the cppfront compiler

#define CPP2_IMPORT_STD          Yes

#include "cpp2util.h"

class test;

class test {
 private: int a {0}; 

 public: auto swap(test&& that) noexcept && -> void;
 public: test() = default;
 public: test(test const&) = delete; /* No 'that' constructor, suppress copy */
 public: auto operator=(test const&) -> void = delete;
};

 auto test::swap(test&& that) noexcept && -> void{
  int temp_a {(*this).a}; 
  a = cpp2::move(that).a;
  that.a = cpp2::move(temp_a);
 }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions