Opened 4 years ago

Last modified 4 years ago

#11 new defect

Compiler uses all Resources when Copying from Generic Function Result

Reported by: ajbeach Owned by:
Priority: minor Component: cfa-cc
Version: 1.0 Keywords:
Cc:

Description

If I try to compile the following code the cfa compiler uses 100% CPU and 100% MEM and crashes the computer.

maybe(char) letter = maybe_value('a');

However the following code compiles with no noticeable slowdown:

maybe(char) letter;
letter = maybe_value('a');
maybe(char) rune = letter;

I also tried annotating the argument, (char)'a', and that got it to work. I'm not sure why as under the current rules that should be a no-op. But it does suggest a resolver issue.


I also tried annotating the call of maybe_value with maybe(char) and got the following error:

*CFA assertion error* from program "cfa-cpp" in "virtual void CodeGen::CodeGenerator::visit(TypeExpr*)" at line 733 in file "CodeGen/CodeGenerator.cc": TypeExpr should not reach code generation.
Stack back trace for: /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp
(0) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::CodeGenerator::visit(TypeExpr*)+0xd2 [0x4630d2]
(1) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::GenType::handleGeneric[abi:cxx11](ReferenceToType*)+0x206 [0x468d56]
(2) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::GenType::visit(StructInstType*)+0x32 [0x46b6f2]
(3) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::genType(Type*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool, bool)+0x1fc [0x4691ac]
(4) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::CodeGenerator::visit(ObjectDecl*)+0xa7 [0x467247]
(5) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::CodeGenerator::visit(DeclStmt*)+0x18 [0x4636d8]
(6) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::CodeGenerator::visit(CompoundStmt*)+0x16c [0x46665c]
(7) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::CodeGenerator::visit(FunctionDecl*)+0xef [0x4670af]
(8) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : CodeGen::generate(std::__cxx11::list<Declaration*, std::allocator<Declaration*> >, std::ostream&, bool, bool, bool, bool)+0x80 [0x462be0]
(9) /home/ajbeach/cfa-cc/lib/cfa/cfa-cpp : main(/*unknown*/)+0x89f [0x45c37f]
CFA Translator error: cfa-cpp failed with signal 6

Some related maybe function definitions (from the new containers/maybe library header)

forall(otype T)
void ?{}(maybe(T) * this, maybe(T) other);

forall(otype T)
maybe(T) ?=?(maybe(T) * this, maybe(T) other);

forall(otype T)
maybe(T) maybe_value(T value);

Change History (3)

comment:1 Changed 4 years ago by ajbeach

Sorry, may have cut too much out of the context. This still seems to cause problems.

void checkNamedConstructors() {
    maybe(char) letter = maybe_value('a');
    assert(has_value(&letter));
    assert('a' == get(&letter));

    maybe(char) rune = maybe_none();
    assert(!has_value(&rune));
}

comment:2 Changed 4 years ago by a3moss

The issue with the code above seems to actually be maybe(char) rune = maybe_none();

The existing resolver is not good at inferring types that don't exist in the parameter list of the function, though I can perhaps take a look at this.

As a workaround for this case, maybe(char) rune = {}; should work.

Andrew pointed out that the following also don't work, I strongly suspect it's the same underlying bug (the error and value types, respectively, are not bound in the parameter list):

result(int, char) answer = result_value( 42 );
result(int, char) nonanswer = result_error( '!' );

Workarounds for the above cases are as follows:

result(int, char) answer = { 1, 42 };
result(int, char) nonanswer = { 0, '!' };

It is worth noting that the resolver prototype already handles these cases (more or less, it doesn't support generic types yet, but it does do inference over return types).

comment:3 Changed 4 years ago by a3moss

Smallest reproduction of this bug (if you comment out line 4 it doesn't occur):

Line 
1struct foo {};
2
3forall(otype T) struct tagged {
4    T t;
5};
6
7forall(otype T) 
8T make() { T r; return r; }
9
10int main() {
11    tagged(foo) f = make();
12}
Last edited 4 years ago by a3moss (previous) (diff)
Note: See TracTickets for help on using tickets.