@@ -402,23 +402,20 @@ void ProgramInfo::exitCompilationUnit() {
402
402
return ;
403
403
}
404
404
405
- bool ProgramInfo::insertIntoExternalFunctionMap (ExternalFunctionMapType &Map,
405
+ void ProgramInfo::insertIntoExternalFunctionMap (ExternalFunctionMapType &Map,
406
406
const std::string &FuncName,
407
407
FVConstraint *NewC,
408
408
FunctionDecl *FD,
409
409
ASTContext *C) {
410
- bool RetVal = false ;
411
410
if (Map.find (FuncName) == Map.end ()) {
412
411
Map[FuncName] = NewC;
413
- RetVal = true ;
414
412
} else {
415
413
auto *OldC = Map[FuncName];
416
414
if (!OldC->hasBody ()) {
417
415
if (NewC->hasBody () ||
418
416
(OldC->numParams () == 0 && NewC->numParams () != 0 )) {
419
417
NewC->brainTransplant (OldC, *this );
420
418
Map[FuncName] = NewC;
421
- RetVal = true ;
422
419
} else {
423
420
// if the current FV constraint is not a definition?
424
421
// then merge.
@@ -450,44 +447,42 @@ bool ProgramInfo::insertIntoExternalFunctionMap(ExternalFunctionMapType &Map,
450
447
DiagnosticsEngine::Fatal, " duplicate definition for function %0" );
451
448
DE.Report (FD->getLocation (), DuplicateDefinitionsID).AddString (FuncName);
452
449
exit (1 );
450
+ } else {
451
+ // The old constraint has a body, but we've encountered another prototype
452
+ // for the function.
453
+ assert (OldC->hasBody () && !NewC->hasBody ());
454
+ // By transplanting the atoms of OldC into NewC, we ensure that any
455
+ // constraints applied to NewC later on constrain the atoms of OldC.
456
+ NewC->brainTransplant (OldC, *this );
453
457
}
454
- // else oldc->hasBody() so we can ignore the newC prototype
455
458
}
456
- return RetVal;
457
459
}
458
460
459
- bool ProgramInfo::insertIntoStaticFunctionMap (StaticFunctionMapType &Map,
461
+ void ProgramInfo::insertIntoStaticFunctionMap (StaticFunctionMapType &Map,
460
462
const std::string &FuncName,
461
463
const std::string &FileName,
462
464
FVConstraint *ToIns,
463
465
FunctionDecl *FD, ASTContext *C) {
464
- bool RetVal = false ;
465
- if (Map.find (FileName) == Map.end ()) {
466
+ if (Map.find (FileName) == Map.end ())
466
467
Map[FileName][FuncName] = ToIns;
467
- RetVal = true ;
468
- } else {
469
- RetVal =
470
- insertIntoExternalFunctionMap (Map[FileName], FuncName, ToIns, FD, C);
471
- }
472
- return RetVal;
468
+ else
469
+ insertIntoExternalFunctionMap (Map[FileName], FuncName, ToIns, FD, C);
473
470
}
474
471
475
- bool ProgramInfo::insertNewFVConstraint (FunctionDecl *FD, FVConstraint *FVCon,
472
+ void ProgramInfo::insertNewFVConstraint (FunctionDecl *FD, FVConstraint *FVCon,
476
473
ASTContext *C) {
477
- bool Ret = false ;
478
474
std::string FuncName = FD->getNameAsString ();
479
475
if (FD->isGlobal ()) {
480
476
// external method.
481
- Ret = insertIntoExternalFunctionMap (ExternalFunctionFVCons, FuncName, FVCon,
482
- FD, C);
477
+ insertIntoExternalFunctionMap (ExternalFunctionFVCons, FuncName, FVCon, FD ,
478
+ C);
483
479
} else {
484
480
// static method
485
481
auto Psl = PersistentSourceLoc::mkPSL (FD, *C);
486
482
std::string FuncFileName = Psl.getFileName ();
487
- Ret = insertIntoStaticFunctionMap (StaticFunctionFVCons, FuncName,
488
- FuncFileName, FVCon, FD, C);
483
+ insertIntoStaticFunctionMap (StaticFunctionFVCons, FuncName, FuncFileName ,
484
+ FVCon, FD, C);
489
485
}
490
- return Ret;
491
486
}
492
487
493
488
void ProgramInfo::specialCaseVarIntros (ValueDecl *D, ASTContext *Context) {
@@ -548,32 +543,39 @@ void ProgramInfo::addVariable(clang::DeclaratorDecl *D,
548
543
// Function Decls have FVConstraints.
549
544
FVConstraint *F = new FVConstraint (D, *this , *AstContext);
550
545
F->setValidDecl ();
551
- PVConstraint *RetExternal = F->getExternalReturn ();
552
- PVConstraint *RetInternal = F->getInternalReturn ();
553
- auto Ret_Ty = FD->getReturnType ();
554
- unifyIfTypedef (Ret_Ty.getTypePtr (), *AstContext, FD, RetExternal);
555
- unifyIfTypedef (Ret_Ty.getTypePtr (), *AstContext, FD, RetInternal);
556
-
557
546
558
547
// Handling of PSL collision for functions is different since we need to
559
548
// consider the static and extern function maps.
560
549
if (Variables.find (PLoc) != Variables.end ()) {
561
550
// Try to find a previous definition based on function name
562
551
if (!getFuncConstraint (FD, AstContext)) {
563
- constrainWildIfMacro (F, FD->getLocation ());
552
+ // No function with the same name exists. It's concerning that
553
+ // something already exists at this source location, but we add the
554
+ // function to the function map anyways. The function map indexes by
555
+ // function name, so there's no collision.
564
556
insertNewFVConstraint (FD, F, AstContext);
557
+ constrainWildIfMacro (F, FD->getLocation ());
565
558
} else {
566
- // FIXME: Visiting same function in same source location twice.
567
- // This shouldn't happen, but it does for some std lib functions
568
- // on our benchmarks programs (vsftpd, lua, etc.). Bailing for
569
- // now, but a real fix will catch and prevent this earlier.
559
+ // A function with the same name exists in the same source location.
560
+ // This happens when a function is defined in a header file which is
561
+ // included in multiple translation units. getFuncConstraint returned
562
+ // non-null, so we know that the definition has been processed already,
563
+ // and there is no more work to do.
570
564
}
571
565
return ;
572
566
}
573
567
574
- /* Store the FVConstraint in the global and Variables maps */
568
+ // Store the FVConstraint in the global and Variables maps. In doing this,
569
+ // insertNewFVConstraint might replace the atoms in F with the atoms of a
570
+ // FVConstraint that already exists in the map. Doing this loses any
571
+ // constraints that might have effected the original atoms, so do not create
572
+ // any constraint on F before this function is called.
575
573
insertNewFVConstraint (FD, F, AstContext);
576
574
575
+ auto RetTy = FD->getReturnType ();
576
+ unifyIfTypedef (RetTy.getTypePtr (), *AstContext, FD, F->getExternalReturn ());
577
+ unifyIfTypedef (RetTy.getTypePtr (), *AstContext, FD, F->getInternalReturn ());
578
+
577
579
NewCV = F;
578
580
// Add mappings from the parameters PLoc to the constraint variables for
579
581
// the parameters.
0 commit comments