Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/ast/ast_generate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2296,8 +2296,8 @@ namespace das {
auto rttiType = new TypeDecl(baseClass);
rttiType->at = baseClass->at;
ExpressionPtr finit = new ExprTypeInfo(baseClass->at, "rtti_classinfo", rttiType);
if ( baseClass->parent ) {
auto fd = (Structure::FieldDeclaration *) baseClass->findField("__rtti");
auto fd = baseClass->parent ? (Structure::FieldDeclaration *) baseClass->findField("__rtti") : nullptr;
if ( fd ) {
fd->init = finit;
fd->parentType = fd->type->isAuto();
fd->generated = true;
Expand All @@ -2323,8 +2323,8 @@ namespace das {
// template classes stay on open "_::": their stamped instances infer in the consumer
// module while the stamped finalizer may live elsewhere, so a strict pin can't see it
ExpressionPtr finit = new ExprAddr(baseClass->at, (baseClass->isTemplate ? "_::" : "__::") + fname);
if ( baseClass->parent ) {
auto fd = (Structure::FieldDeclaration *) baseClass->findField("__finalize");
auto fd = baseClass->parent ? (Structure::FieldDeclaration *) baseClass->findField("__finalize") : nullptr;
if ( fd ) {
auto castT = new TypeDecl(Type::autoinfer, baseClass->at);
fd->init = new ExprCast(baseClass->at, finit, castT);
fd->parentType = fd->type->isAuto();
Expand Down
7 changes: 7 additions & 0 deletions src/ast/ast_infer_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2716,6 +2716,7 @@ namespace das {
return new ExprConstBool(expr->at, ft != nullptr);
} else {
if (expr->trait == "safe_has_field") {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how so? why is this an AST change??

reportAstChanged();
return new ExprConstBool(expr->at, false);
} else {
error("typeinfo(has_field<" + expr->subtrait + "> ...) is only defined for structures and handled types, " + describeType(expr->typeexpr), "", "",
Expand All @@ -2730,6 +2731,7 @@ namespace das {
return new ExprConstBool(expr->at, it != ann.end());
} else {
if (expr->trait == "struct_safe_has_annotation") {
reportAstChanged();
return new ExprConstBool(expr->at, false);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

} else {
error("typeinfo(struct_has_annotation<" + expr->subtrait + "> ...) is only defined for structures, " + describeType(expr->typeexpr), "", "",
Expand All @@ -2742,6 +2744,7 @@ namespace das {
auto it = find_if(ann.begin(), ann.end(), [&](const AnnotationDeclarationPtr &pa) { return pa->annotation->name == expr->subtrait; });
if (it == ann.end()) {
if (expr->trait == "struct_safe_has_annotation_argument") {
reportAstChanged();
return new ExprConstBool(expr->at, false);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same again. why is this an ast change?

} else {
error("typeinfo(struct_has_annotation_argument<" + expr->subtrait + ";" + expr->extratrait + "> ...) annotation not found ", "", "",
Expand All @@ -2755,6 +2758,7 @@ namespace das {
}
} else {
if (expr->trait == "struct_safe_has_annotation_argument") {
reportAstChanged();
return new ExprConstBool(expr->at, false);
} else {
error("typeinfo(struct_has_annotation_argument<" + expr->subtrait + "> ...) is only defined for structures, " + describeType(expr->typeexpr), "", "",
Expand Down Expand Up @@ -4600,6 +4604,9 @@ namespace das {
return Visitor::visit(expr);
}
expr->variable = var;
if (var->type->isExprType()) {
return Visitor::visit(expr);
}
TypeDecl::clone(expr->type, var->type);
expr->type->ref = true;
return Visitor::visit(expr);
Expand Down
13 changes: 7 additions & 6 deletions src/ast/ast_unused.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,7 @@ namespace das {
// Op1
virtual void preVisit ( ExprOp1 * expr ) override {
Visitor::preVisit(expr);
if ( !expr->func ) return;
auto sef = getSideEffects(expr->func);
markPassMutableOperand(expr->func, 0, expr->subexpr);
if ( sef & uint32_t(SideEffects::modifyArgument) ) {
Expand All @@ -699,6 +700,7 @@ namespace das {
// Op2
virtual void preVisit ( ExprOp2 * expr ) override {
Visitor::preVisit(expr);
if ( !expr->func ) return;
auto sef = getSideEffects(expr->func);
markPassMutableOperand(expr->func, 0, expr->left);
markPassMutableOperand(expr->func, 1, expr->right);
Expand All @@ -716,12 +718,11 @@ namespace das {
// Op3
virtual void preVisit ( ExprOp3 * expr ) override {
Visitor::preVisit(expr);
auto sef = expr->func ? getSideEffects(expr->func) : 0;
if ( expr->func ) {
markPassMutableOperand(expr->func, 0, expr->subexpr);
markPassMutableOperand(expr->func, 1, expr->left);
markPassMutableOperand(expr->func, 2, expr->right);
}
if ( !expr->func ) return;
auto sef = getSideEffects(expr->func);
markPassMutableOperand(expr->func, 0, expr->subexpr);
markPassMutableOperand(expr->func, 1, expr->left);
markPassMutableOperand(expr->func, 2, expr->right);
if ( sef & uint32_t(SideEffects::modifyArgument) ) {
auto condT = expr->subexpr->type;
if ( condT->isRefOrPointer() && !condT->constant ) {
Expand Down
13 changes: 13 additions & 0 deletions tests/language/failed_class_parent_rejected.das
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// A class deriving from a class whose own declaration is rejected. The `class B : A` error
// returns before B gets its generated __rtti and __finalize fields, so `class C : B` - which is
// accepted - reaches field generation with a parent that carries neither.
options gen2
expect 30134

struct A;
class B : A;
class C : B;

[export]
def main {
}
14 changes: 14 additions & 0 deletions tests/language/failed_global_dim_self_reference.das
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// A global whose fixed-array dimension names the variable it declares. The dimension expression
// sits inside the type it dimensions, so a reference that takes the variable's own type takes a
// type holding that reference; with two dimensions each infer pass squares the last one's copy.
// The array clone in main is what keeps the passes coming.
options gen2
expect 30109:2

let zz : int[zz][zz]

[export]
def main {
var cb : array<int>
cb := cb
}
28 changes: 28 additions & 0 deletions tests/language/failed_op2_typeinfo_safe_traits.das
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// A safe_* typeinfo trait that answers false replaces its node, so it tells infer to run again.
// Each arm takes its value from a nested typeinfo, or from an index that folds, so the trait
// resolves one pass late - in a pass where nothing else changes, which is the pass that catches a
// missing signal. Keep this file free of anything that keeps signalling (a print's string builder
// will do it): that grants the enclosing operator a repair pass and the arms stop proving anything.
// Without the signal every arm reports 50613 instead, the reported input included.
options gen2
expect 30341

[comment(i = 1)]
struct TsrAnnotated {
x : int
}

var g_tsr_annotated : TsrAnnotated[8]

[export]
def main {
var a = true
a &&= typeinfo safe_has_field < no_such_field > (typeinfo is_ref(1))
var b = true
b &&= typeinfo struct_safe_has_annotation < no_such_annotation > (typeinfo is_ref(1))
var c = true
c &&= typeinfo struct_safe_has_annotation_argument < no_such_annotation; no_such_argument > (typeinfo is_ref(1))
var d = true
d &&= typeinfo struct_safe_has_annotation_argument < no_such_annotation; no_such_argument > (g_tsr_annotated[typeinfo sizeof(type<int>)])
1 &&= typeinfo safe_has_field < no_such_type > (typeinfo is_ref(1))
}
Loading