Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2991,6 +2991,9 @@ "parameter may not be qualified with an address space">; def err_field_with_address_space : Error< "field may not be qualified with an address space">; +def err_qualifier_with_address_space : Error< + "qualifier '%select{const|volatile}0' %select{needed|invalid}1 " + "for variables in address space '%2'">; def err_compound_literal_with_address_space : Error< "compound literal in function scope may not be qualified with an address space">; def err_address_space_mismatch_templ_inst : Error< Index: clang/lib/Basic/Targets/AVR.cpp =================================================================== --- clang/lib/Basic/Targets/AVR.cpp +++ clang/lib/Basic/Targets/AVR.cpp @@ -308,6 +308,7 @@ Builder.defineMacro("__AVR"); Builder.defineMacro("__AVR__"); Builder.defineMacro("__ELF__"); + Builder.defineMacro("__flash", "__attribute__((address_space(1)))"); if (!this->CPU.empty()) { auto It = llvm::find_if( Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -21,6 +21,7 @@ #include "clang/AST/RecordLayout.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/CodeGen/SwiftCallingConv.h" #include "llvm/ADT/SmallBitVector.h" @@ -8032,6 +8033,17 @@ AVRTargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(std::make_unique(CGT)) {} + LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const { + // Check if a global/static variable is defined within address space 1 + // but not constant. + if (toTargetAddressSpace(D->getType().getAddressSpace()) == 1 && + !D->getType().isConstQualified()) + CGM.getDiags().Report(D->getLocation(), + diag::err_qualifier_with_address_space) + << 0 << 0 << "__flash"; + return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D); + } + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override { if (GV->isDeclaration()) Index: clang/test/CodeGen/address-space-avr.c =================================================================== --- clang/test/CodeGen/address-space-avr.c +++ clang/test/CodeGen/address-space-avr.c @@ -3,10 +3,16 @@ // Test that function declarations in nonzero address spaces without prototype // are called correctly. +// CHECK: @var0 {{.*}} addrspace(1) constant i16 333 +// CHECK: @bar.var1 {{.*}} addrspace(1) constant i16 555 // CHECK: define{{.*}} void @bar() addrspace(1) // CHECK: call addrspace(1) void bitcast (void (...) addrspace(1)* @foo to void (i16) addrspace(1)*)(i16 3) // CHECK: declare void @foo(...) addrspace(1) + +__flash const int var0 = 333; + void foo(); void bar(void) { + static __flash const int var1 = 555; foo(3); } Index: clang/test/CodeGen/avr-flash.c =================================================================== --- /dev/null +++ clang/test/CodeGen/avr-flash.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple avr -emit-llvm-only -verify %s + +static __flash int arr[] = {4, 6, 1, 2, 5}; // expected-error {{qualifier 'const' needed for variables in address space '__flash'}} + +int foo(int i, int j) { + static __flash int b[] = {4, 6, 1, 2, 5}; // expected-error {{qualifier 'const' needed for variables in address space '__flash'}} + return arr[i] + b[j]; +}