@@ -612,6 +612,45 @@ void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize,
612612 *OrShadowOffset = Mapping.OrShadowOffset ;
613613}
614614
615+ void removeASanIncompatibleFnAttributes (Function &F, bool ReadsArgMem) {
616+ // Sanitizer checks read from shadow, which invalidates memory(argmem: *).
617+ //
618+ // This is not only true for sanitized functions, because AttrInfer can
619+ // infer those attributes on libc functions, which is not true if those
620+ // are instrumented (Android) or intercepted.
621+ //
622+ // We might want to model ASan shadow memory more opaquely to get rid of
623+ // this problem altogether, by hiding the shadow memory write in an
624+ // intrinsic, essentially like in the AArch64StackTagging pass. But that's
625+ // for another day.
626+
627+ // The API is weird. `onlyReadsMemory` actually means "does not write", and
628+ // `onlyWritesMemory` actually means "does not read". So we reconstruct
629+ // "accesses memory" && "does not read" <=> "writes".
630+ bool Changed = false ;
631+ if (!F.doesNotAccessMemory ()) {
632+ bool WritesMemory = !F.onlyReadsMemory ();
633+ bool ReadsMemory = !F.onlyWritesMemory ();
634+ if ((WritesMemory && !ReadsMemory) || F.onlyAccessesArgMemory ()) {
635+ F.removeFnAttr (Attribute::Memory);
636+ Changed = true ;
637+ }
638+ }
639+ if (ReadsArgMem) {
640+ for (Argument &A : F.args ()) {
641+ if (A.hasAttribute (Attribute::WriteOnly)) {
642+ A.removeAttr (Attribute::WriteOnly);
643+ Changed = true ;
644+ }
645+ }
646+ }
647+ if (Changed) {
648+ // nobuiltin makes sure later passes don't restore assumptions about
649+ // the function.
650+ F.addFnAttr (Attribute::NoBuiltin);
651+ }
652+ }
653+
615654ASanAccessInfo::ASanAccessInfo (int32_t Packed)
616655 : Packed(Packed),
617656 AccessSizeIndex ((Packed >> kAccessSizeIndexShift ) & kAccessSizeIndexMask),
@@ -1237,7 +1276,9 @@ void AddressSanitizerPass::printPipeline(
12371276 OS, MapClassName2PassName);
12381277 OS << ' <' ;
12391278 if (Options.CompileKernel )
1240- OS << " kernel" ;
1279+ OS << " kernel;" ;
1280+ if (Options.UseAfterScope )
1281+ OS << " use-after-scope" ;
12411282 OS << ' >' ;
12421283}
12431284
@@ -1251,6 +1292,11 @@ AddressSanitizerPass::AddressSanitizerPass(
12511292
12521293PreservedAnalyses AddressSanitizerPass::run (Module &M,
12531294 ModuleAnalysisManager &MAM) {
1295+ // Return early if nosanitize_address module flag is present for the module.
1296+ // This implies that asan pass has already run before.
1297+ if (checkIfAlreadyInstrumented (M, " nosanitize_address" ))
1298+ return PreservedAnalyses::all ();
1299+
12541300 ModuleAddressSanitizer ModuleSanitizer (
12551301 M, Options.InsertVersionCheck , Options.CompileKernel , Options.Recover ,
12561302 UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);
@@ -2730,6 +2776,9 @@ int ModuleAddressSanitizer::GetAsanVersion(const Module &M) const {
27302776bool ModuleAddressSanitizer::instrumentModule (Module &M) {
27312777 initializeCallbacks (M);
27322778
2779+ for (Function &F : M)
2780+ removeASanIncompatibleFnAttributes (F, /* ReadsArgMem=*/ false );
2781+
27332782 // Create a module constructor. A destructor is created lazily because not all
27342783 // platforms, and not all modules need it.
27352784 if (ConstructorKind == AsanCtorKind::Global) {
0 commit comments