Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -2312,7 +2312,14 @@ // handling. GV->setConstant(isTypeConstant(D->getType(), false)); - GV->setAlignment(getContext().getDeclAlign(D).getQuantity()); + if (LangOpts.Sanitize.has(SanitizerKind::Alignment) && !IsForDefinition && + (D->getStorageClass() == SC_Extern || + D->getStorageClass() == SC_PrivateExtern)) { + // The alignment sanitizer can catch more bugs if we don't attach + // alignment info to extern globals. + } else { + GV->setAlignment(getContext().getDeclAlign(D).getQuantity()); + } setLinkageAndVisibilityForGV(GV, D); Index: test/CodeGenCXX/ubsan-global-alignment.cpp =================================================================== --- test/CodeGenCXX/ubsan-global-alignment.cpp +++ test/CodeGenCXX/ubsan-global-alignment.cpp @@ -5,18 +5,27 @@ }; extern S g_S; +__private_extern__ S pe_S; extern S array_S[]; -// CHECK-LABEL: define i32 @_Z18load_extern_global -int load_extern_global() { - // FIXME: The IR builder constant-folds the alignment check away to 'true' - // here, so we never call the diagnostic. This is PR32630. - // CHECK-NOT: ptrtoint i32* {{.*}} to i32, !nosanitize +// CHECK-LABEL: define i32 @_Z19load_extern_global1 +int load_extern_global1() { + // CHECK: br i1 icmp eq (i64 and (i64 ptrtoint (%struct.S* @g_S to i64), i64 3), i64 0), {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_type_mismatch // CHECK: [[I:%.*]] = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @g_S, i32 0, i32 0), align 4 // CHECK-NEXT: ret i32 [[I]] return g_S.I; } +// CHECK-LABEL: define i32 @_Z19load_extern_global2 +int load_extern_global2() { + // CHECK: br i1 icmp eq (i64 and (i64 ptrtoint (%struct.S* @pe_S to i64), i64 3), i64 0), {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_type_mismatch + // CHECK: [[I:%.*]] = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @pe_S, i32 0, i32 0), align 4 + // CHECK-NEXT: ret i32 [[I]] + return pe_S.I; +} + // CHECK-LABEL: define i32 @_Z22load_from_extern_array int load_from_extern_array(int I) { // CHECK: [[I:%.*]] = getelementptr inbounds %struct.S, %struct.S* {{.*}}, i32 0, i32 0