Add incomplete type error

This commit is contained in:
augustin64 2024-01-04 21:22:35 +01:00
parent ac191716d9
commit 6a646ecec7
5 changed files with 44 additions and 0 deletions

View File

@ -214,6 +214,9 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
throw TypeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier); throw TypeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier);
Type type = try_string_to_type(type_string, type_token.pos); Type type = try_string_to_type(type_string, type_token.pos);
if (type.type == TypeType::Void)
throw TypeError(ErrorType::IncompleteType, token.pos, {});
memory.declare(identifier, type); memory.declare(identifier, type);
return {}; return {};
@ -229,6 +232,9 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
throw TypeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier); throw TypeError(ErrorType::AlreadyDeclaredIdentifier, token.pos, identifier);
Type type = try_string_to_type(type_string, type_token.pos); Type type = try_string_to_type(type_string, type_token.pos);
if (type.type == TypeType::Void)
throw TypeError(ErrorType::IncompleteType, token.pos, {});
memory.declare(identifier, type); memory.declare(identifier, type);
get_cast(type, analyze(node.children[2], memory), get_node_pos(node)); get_cast(type, analyze(node.children[2], memory), get_node_pos(node));
@ -295,6 +301,15 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
} }
} }
for (int i=1; i < (int)prototype.size(); i++) {
if (get<0>(prototype.at(i)).type == TypeType::Void) {
InnerNode args_node = get<InnerNode>(node.children[2]);
InnerNode declaration_node = get<InnerNode>(args_node.children[i-1]);
CodePosition type_pos = get_node_pos(declaration_node.children[0]);
throw TypeError(ErrorType::IncompleteType, type_pos, {});
}
}
memory.declare(function_name, type); memory.declare(function_name, type);
return {}; return {};
@ -335,6 +350,15 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
} }
} }
for (int i=1; i < (int)prototype.size(); i++) {
if (get<0>(prototype.at(i)).type == TypeType::Void) {
InnerNode args_node = get<InnerNode>(node.children[2]);
InnerNode declaration_node = get<InnerNode>(args_node.children[i-1]);
CodePosition type_pos = get_node_pos(declaration_node.children[0]);
throw TypeError(ErrorType::IncompleteType, type_pos, {});
}
}
memory.declare(function_name, type); memory.declare(function_name, type);
memory.update(function_name, node.children[3]); memory.update(function_name, node.children[3]);

View File

@ -46,6 +46,7 @@ string UserError::get_message(void) const {
case ErrorType::IncompatibleDefinition: return "Declaration of '"+get<string>(this->data)+"' is incompatible with previous prototype"; case ErrorType::IncompatibleDefinition: return "Declaration of '"+get<string>(this->data)+"' is incompatible with previous prototype";
case ErrorType::UnexpectedArgumentCount: return "Expected "+to_string(get<int>(this->data))+" arguments to function call"; case ErrorType::UnexpectedArgumentCount: return "Expected "+to_string(get<int>(this->data))+" arguments to function call";
case ErrorType::IncompatibleReturnValue: return "Return value type does not match the function type"; case ErrorType::IncompatibleReturnValue: return "Return value type does not match the function type";
case ErrorType::IncompleteType: return "Incomplete type is not allowed";
// Runtime // Runtime
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'"; case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";

View File

@ -45,6 +45,7 @@ enum class ErrorType {
IncompatibleDefinition, // function declaration incompatible with prototype IncompatibleDefinition, // function declaration incompatible with prototype
UnexpectedArgumentCount, UnexpectedArgumentCount,
IncompatibleReturnValue, IncompatibleReturnValue,
IncompleteType, // void x
// Runtime // Runtime
UnknownIdentifier, UnknownIdentifier,

View File

@ -98,5 +98,17 @@ int main() {
true true
); );
_TEST_ASSERT(
_TEST_IS_EXCEPTION(execute("int f(int x, void y);"), ErrorType::IncompleteType),
"Argument void (prototype)",
true
);
_TEST_ASSERT(
_TEST_IS_EXCEPTION(execute("int f(int x, void y) { return x+2; };"), ErrorType::IncompleteType),
"Argument void (déclaration)",
true
);
return 0; return 0;
} }

View File

@ -35,6 +35,12 @@ int main() {
true true
); );
_TEST_ASSERT(
_TEST_IS_EXCEPTION(execute("void x;"), ErrorType::IncompleteType),
"Type void",
true
);
_TEST_ASSERT( _TEST_ASSERT(
_TEST_NO_EXCEPTION(holds_alternative<monostate>(execute("int x; { int x; }"))), _TEST_NO_EXCEPTION(holds_alternative<monostate>(execute("int x; { int x; }"))),
"Identifieur déjà défini dans une autre scope", "Identifieur déjà défini dans une autre scope",