@@ -323,17 +323,16 @@ bool ProgramInfo::link() {
323323 }
324324 }
325325
326- // For every global function that is an unresolved external, constrain
327- // its parameter types to be wild. Unless it has a bounds-safe annotation.
328- for (const auto &U : ExternFunctions) {
326+ // For every global function that is an unresolved external, constrain
327+ // its parameter types to be wild. Unless it has a bounds-safe annotation.
328+ for (const auto &U : ExternalFunctionFVCons) {
329+ std::string FuncName = U.first ;
330+ FVConstraint *G = U.second ;
329331 // If we've seen this symbol, but never seen a body for it, constrain
330332 // everything about it.
331- std::string FuncName = U.first ;
332- if (!U.second && !isExternOkay (FuncName)) {
333- // Some global symbols we don't need to constrain to wild, like
334- // malloc and free. Check those here and skip if we find them.
335- FVConstraint *G = getExtFuncDefnConstraint (FuncName);
336- assert (" Function constraints could not be found!" && G != nullptr );
333+ // Some global symbols we don't need to constrain to wild, like
334+ // malloc and free. Check those here and skip if we find them.
335+ if (!G->hasBody () && !isExternOkay (FuncName)) {
337336
338337 // If there was a checked type on a variable in the input program, it
339338 // should stay that way. Otherwise, we shouldn't be adding a checked type
@@ -348,14 +347,35 @@ bool ProgramInfo::link() {
348347 G->getParamVar (I)->constrainToWild (CS, Rsn);
349348 }
350349 }
350+ // repeat for static functions
351+ //
352+ // Static functions that don't have a body will always cause a linking
353+ // error during compilation. They may still be useful as code is developed,
354+ // so we treat them as if they are external, and constrain parameters
355+ // to wild as appropriate.
356+ for (const auto &U :StaticFunctionFVCons) {
357+ for (const auto &V :U.second ) {
358+
359+ std::string FileName = U.first ;
360+ std::string FuncName = V.first ;
361+ FVConstraint *G = V.second ;
362+ if (!G->hasBody ()) {
363+
364+ std::string Rsn =
365+ " Unchecked pointer in parameter or return of static function " +
366+ FuncName + " in " + FileName;
367+ if (!G->getReturnVar ()->getIsGeneric ())
368+ G->getReturnVar ()->constrainToWild (CS, Rsn);
369+ for (unsigned I = 0 ; I < G->numParams (); I++)
370+ if (!G->getParamVar (I)->getIsGeneric ())
371+ G->getParamVar (I)->constrainToWild (CS, Rsn);
372+ }
373+ }
374+ }
351375
352376 return true ;
353377}
354378
355- bool ProgramInfo::isAnExternFunction (const std::string &FName) {
356- return !ExternFunctions[FName];
357- }
358-
359379// Populate Variables, VarDeclToStatement, RVariables, and DepthMap with
360380// AST data structures that correspond do the data stored in PDMap and
361381// ReversePDMap.
@@ -463,13 +483,6 @@ bool ProgramInfo::insertNewFVConstraint(FunctionDecl *FD, FVConstraint *FVCon,
463483 // external method.
464484 Ret = insertIntoExternalFunctionMap (ExternalFunctionFVCons, FuncName, FVCon,
465485 FD, C);
466- bool IsDef = FVCon->hasBody ();
467- if (IsDef) {
468- ExternFunctions[FuncName] = true ;
469- } else {
470- if (!ExternFunctions[FuncName])
471- ExternFunctions[FuncName] = false ;
472- }
473486 } else {
474487 // static method
475488 auto Psl = PersistentSourceLoc::mkPSL (FD, *C);
0 commit comments