Skip to content

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

@amc522

Description

@amc522

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);
 }

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