Changeset 81e768d for src/Validate
- Timestamp:
- Nov 28, 2024, 4:34:08 PM (8 weeks ago)
- Branches:
- master
- Children:
- 46c4dea
- Parents:
- f5e37a4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/ReplaceTypedef.cpp
rf5e37a4 r81e768d 120 120 } 121 121 } 122 123 122 struct VarLenChecker : public ast::WithShortCircuiting { 124 123 bool result = false; … … 126 125 void previsit( ast::ArrayType const * at ) { result |= at->isVarLen; } 127 126 }; 128 127 static bool hasVarLen( const ast::Type * t ) { 128 return ast::Pass<VarLenChecker>::read( t ); 129 } 130 struct ArrayTypeExtractor { 131 std::vector<const ast::ArrayType *> result; 132 void postvisit( const ast::ArrayType * at ) { 133 result.push_back( at ); 134 } 135 }; 136 static bool dimensionPresenceMismatched( const ast::Type * t0, const ast::Type * t1) { 137 std::vector<const ast::ArrayType *> at0s = std::move( 138 ast::Pass<ArrayTypeExtractor>::read( t0 ) ); 139 std::vector<const ast::ArrayType *> at1s = std::move( 140 ast::Pass<ArrayTypeExtractor>::read( t1 ) ); 141 assert( at0s.size() == at1s.size() ); 142 for (size_t i = 0; i < at0s.size(); i++) { 143 const ast::ArrayType * at0 = at0s[i]; 144 const ast::ArrayType * at1 = at1s[i]; 145 assert( ResolvExpr::typesCompatible( at0, at1 ) ); 146 if ( (at0->dimension != nullptr) != (at1->dimension != nullptr) ) return true; 147 } 148 return false; 149 } 129 150 ast::Decl const * ReplaceTypedefCore::postvisit( 130 151 ast::TypedefDecl const * decl ) { … … 133 154 ast::Type const * t0 = decl->base; 134 155 ast::Type const * t1 = typedefNames[ decl->name ].first->base; 156 // [hasVarLen] 135 157 // Cannot redefine VLA typedefs. Note: this is slightly incorrect, 136 158 // because our notion of VLAs at this point in the translator is … … 139 161 // constant/enumerator. The effort required to fix this corner case 140 162 // likely outweighs the utility of allowing it. 163 // [dimensionPresenceMismatched] 164 // Core typesCompatible logic interprets absent dimensions as wildcards, 165 // i.e. float[][*] matches float[][42]. 166 // For detecting incompatible typedefs, we have to interpret them verbatim, 167 // i.e. float[] is different than float[42]. 168 // But typesCompatible does assure that the pair of types is structurally 169 // consistent, outside of the dimension expressions. This assurance guards 170 // the dimension-presence traversal. So this traversal logic can (and does) 171 // assume that ArrayTypes will be encountered in analogous places. 141 172 if ( !ResolvExpr::typesCompatible( t0, t1 ) 142 || ast::Pass<VarLenChecker>::read( t0 ) 143 || ast::Pass<VarLenChecker>::read( t1 ) ) { 173 || hasVarLen( t0 ) 174 || hasVarLen( t1 ) 175 || dimensionPresenceMismatched( t0, t1 ) ) { 144 176 SemanticError( decl->location, "Cannot redefine typedef %s", decl->name.c_str() ); 145 177 }
Note: See TracChangeset
for help on using the changeset viewer.