hsutter / cppfront

A personal experimental C++ Syntax 2 -> Syntax 1 compiler
Other
5.23k stars 224 forks source link

[BUG] Issue with the newly added "identifier : const = value " functionality #1138

Open HALL9kv0 opened 1 week ago

HALL9kv0 commented 1 week ago

Describe the bug

The identifier : const = value functionality is not consistent. 1) Doesn't work at all in global/namespace scope (might be a feature, not a bug) and 2) it results in a g++ error when trying to initialize an std::array, even though it is used inside the main scope (probably a bug).

To Reproduce

A) The following works:

N : const int =2;

main: () -> int = {
   arr: std::array<int,N> =();
}

B) This one also works:

main: () -> int = {
N : const  =2;
}

C) The following results to a cppfront error :

N : const =2;

main: () -> int = {
   arr: std::array<int,N> =();
}

error: namespace scope objects must have a concrete type, not a deduced type

D) Then when I make the declaration inside the main function scope, it compiles to cpp but we get a g++ error.

main: () -> int = {
    N : const =2;

   arr: std::array<int,N> =();
}

error: the value of ‘N’ is not usable in a constant expression 7 | arr: std::array<int,N> =(); | ~~^~ main.cpp2:5:6: note: ‘int N’ is not const 5 | N : const =2; | ^ main.cpp2:7:29: note: in template argument for type ‘long unsigned int’ 7 | arr: std::array<int,N> =();

and the cpp file is :

[[nodiscard]] auto main() -> int{
    auto N {2}; 

   std::array<int,cpp2::move(N)> arr {}; 
}

Command lines including which C++ compiler you are using: cppfront -p main.cpp2 && g++ -std=c++23 main.cpp

Expected result The auto N {2}; to be a const in the cpp file.

As a user, I expected to be able to write N: const =2 in the global/namespace scope also, and to be able to use it to initialize the std::array. If I'm not mistaken, case D is indeed a bug, but case C is a feature, as namespace objects cannot have a deduced type.

Should we have an exception to the rule regarding the C case, when the expression is const/constexpr?

bluetarpmedia commented 1 week ago

Just to expand on case D) above, this Cpp2:

main: () -> int = {
    a: const _ = 1;
    b: const   = 2;
}

lowers to:

[[nodiscard]] auto main() -> int{
    auto const a {1}; 
    auto b {2}; 
}

Repro on Godbolt

sookach commented 1 week ago

From my closed pr (referring to case D): https://github.com/hsutter/cppfront/commit/d0836be2bff6a65d6ffb081a3d4cb14ccc49c25f suppresses the error, but returning a default object drops the pc_qualifiers.

Due to cppfront's being a backtracking parser, it does the hokey pokey, entering and exiting parse sections until it's successful, and with my adjustment of defaulting to return the built up type_id node all the time, the parser gets thrown off in the instances where it is just testing waters by trying to parse a type id. It would be nice to convert cppfront to a predictive parser (nothing in the grammar stands out as an obstacle), but at this stage, that would be quite the undertaking.