source: src/Validate/CheckAssertions.cpp @ 82a5ea2

Last change on this file since 82a5ea2 was 82a5ea2, checked in by Andrew Beach <ajbeach@…>, 6 days ago

Added checks for (and a test to check the checks) assertions we will not be able to adapt. Using an adapted version of Mike's error message.

  • Property mode set to 100644
File size: 2.6 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// CheckAssertions.cpp --
8//
9// Author           : Andrew Beach
10// Created On       : Thu Sep  5 14:43:00 2024
11// Last Modified By : Andrew Beach
12// Last Modified On : Thu Sep  5 14:43:00 2024
13// Update Count     : 0
14//
15
16#include "CheckAssertions.hpp"
17
18#include "AST/Decl.hpp"
19#include "AST/Pass.hpp"
20#include "AST/Type.hpp"
21#include "Common/SemanticError.hpp"
22#include "GenPoly/GenPoly.hpp"
23
24namespace Validate {
25
26namespace {
27
28/// Check for dynamic (sized polymorphic) variadic assertions.
29struct VariadicAssertionCore final {
30        void checkAssertion( GenPoly::TypeVarMap const & typeVars,
31                        ast::FunctionDecl const * assert ) {
32                if ( ast::FixedArgs != assert->type->isVarArgs
33                                && needsAdapter( assert->type, typeVars ) ) {
34                        SemanticError( assert,
35                                "Cannot assert a function that both has by-value polymorphic "
36                                "parameters or return values, and also takes variadic (...) "
37                                "parameters. Consider using a va_list parameter instead.\n" );
38                }
39        }
40
41        template<typename T>
42        void checkList(
43                        GenPoly::TypeVarMap const & typeVars,
44                        SemanticErrorException & errors,
45                        std::vector<ast::ptr<T>> const & members ) {
46                for ( const ast::ptr<T> & member : members ) {
47                        try {
48                                if ( auto func = member.template as<ast::FunctionDecl>() ) {
49                                        checkAssertion( typeVars, func );
50                                }
51                        } catch ( SemanticErrorException & error ) {
52                                errors.append( error );
53                        }
54                }
55        }
56
57        void postvisit( ast::FunctionDecl const * decl ) {
58                GenPoly::TypeVarMap typeVars;
59                SemanticErrorException errors;
60                makeTypeVarMap( decl, typeVars );
61                checkList( typeVars, errors, decl->assertions );
62                if ( !errors.isEmpty() ) { throw errors; }
63        }
64
65        void checkAggr( bool checkMembers,
66                        ast::AggregateDecl const * decl ) {
67                SemanticErrorException errors;
68                GenPoly::TypeVarMap typeVars;
69                for ( auto & param : decl->params ) {
70                        addToTypeVarMap( param, typeVars );
71                        checkList( typeVars, errors, param->assertions );
72                }
73                if ( checkMembers ) checkList( typeVars, errors, decl->members );
74                if ( !errors.isEmpty() ) { throw errors; }
75        }
76
77        void postvisit( ast::StructDecl const * decl ) {
78        checkAggr( false, decl );
79        }
80
81        void postvisit( ast::UnionDecl const * decl ) {
82                checkAggr( false, decl );
83        }
84
85        void postvisit( ast::TraitDecl const * decl ) {
86                checkAggr( true, decl );
87        }
88};
89
90} // namespace
91
92void checkAssertions( ast::TranslationUnit & transUnit ) {
93        ast::Pass<VariadicAssertionCore>::run( transUnit );
94}
95
96} // namespace Validate
Note: See TracBrowser for help on using the repository browser.