Dlang增加了Borrowcheckker

2020-05-20 05:34:13

D 2.092.0中所有错误修复和增强的列表。CLI开关-REVERT=IMPORT和-TRANSION=CHECKIMPORTS已被删除,这些开关已不执行任何操作且已弃用一段时间。编译器将不再识别它们。

GNU ABI标签是GCC 5.1中用C++11添加的一个特性。为了让D完全支持标准C++库,DMD现在可以识别特殊的UDA gnuAbiTag,它在core.attribute中声明,在object中公开别名(因此不需要导入任何内容就可以使用它)。ABI标记是大多数用户不需要与之交互低级功能,但可用于绑定到需要它的C++库。特别是,当面向C++11及更高版本(DMD switch-extern-std={c++11,c++14,c++17})时,需要绑定std::string。

一个符号上一次只能出现一个gnuAbiTag。数组条目的顺序并不重要(它们根据输出进行排序)。只有将-extern-std=c++11或更高版本传递给编译器,UDA才会生效。默认值(-extern-std=c++98)将忽略UDA。此UDA只能应用于外部(C++)符号,不能应用于命名空间。

不是外部(D)的模块构造函数和析构函数是弃用的模块构造函数和析构函数(共享或非共享)可以标记为与外部(D)不同的链接,这会影响它们的损坏。由于这样的损坏是简单且可预测的,如果在类似条件下声明两个相同类型的构造函数/析构函数,则冲突的可能性非常小,例如,如果模块A中的第三个模块构造函数在线479上,模块B中的第三个模块构造函数也在线479上,则它们将具有相同的损坏。

虽然在实践中不太可能触发这样的错误,但受影响的符号现在会触发一条弃用消息。

DIP25违规现在将默认发出弃用DIP25从v2.067.0开始就可用了,首先是作为它自己的开关,最近是在-review=dip25开关下。该功能现在功能齐全,并且已经建立在例如DIP1000的基础上。

从本版本开始,在将-PREVIEW=dip25传递给编译器时会触发错误的代码也将在没有-PREVIEW=dip25的情况下触发一条弃用消息。交换机的行为不变(仍会发出错误)。

DIP25旨在使@Safe代码不可能引用析构对象。实际上,可能需要函数和方法返回对其参数的引用,才能将方法或参数限定为返回,正如编译器所提示的那样。

struct foo{int x;//返回`this.x`转义对参数`this`的引用,可能使用`rereturn`ref int method()/*return*/{return this.x;}}//返回`v`转义对参数`v`的引用,可能使用`rereturn`ref int标识(/*return*/ref int v){return v;}。

在这两种情况下,取消对返回注释的注释将安抚编译器。DIP25的完整说明可在此处找到。

指针的原型所有权/借用系统指针的所有权/借用(又名OB)系统可以保证解除引用的指针指向有效的内存对象。

这是一个适用于D的原型OB系统。它最初只适用于指针,不适用于动态数组、类引用、引用或聚合的指针字段。添加对这类支持会增加复杂性,但不会改变其性质,因此将其推迟到以后。RAII对象可以安全地管理它们自己的内存,因此不在OB的覆盖范围内。指针是否使用GC或其他存储分配器分配内存对OB来说无关紧要,它们没有区别,处理方式也是一样的。

系统仅在使用@live属性注释的函数中处于活动状态。它是在进行语义处理之后应用的,纯粹是为了检查是否违反OB规则。未添加任何新语法。不会更改生成的代码。如果@live函数调用非@live函数,则被调用的函数应该呈现与@live兼容的接口,尽管它没有被选中。如果非@live函数调用@live函数,则传递的参数应遵循@live约定。

它不会检测取消引用空指针或可能的空指针的尝试。这是不可行的,因为当前没有将类型批注为非空指针的方法。

对于每个内存对象,可以只存在一个指向它的变异指针,也可以存在多个非变异(只读)指针。

单个变异指针称为内存对象的所有者。它可传递地拥有内存对象和可从其访问的所有内存对象(即内存对象图)。因为它是指向该内存对象的唯一指针,所以它可以安全地管理内存(更改其形状、分配、释放和调整大小),而不会从可能指向它的任何其他指针(无论是否发生变化)下拉出地毯。

如果有多个指向内存对象图的只读指针,则它们可以安全地从内存对象图中读取,而不必担心更改了内存对象图。

设计的其余部分涉及指针如何成为所有者、只读指针和无效指针,以及如何始终保持核心OB原则。

唯一被跟踪的指针是那些在@live函数中声明为this的指针、函数参数或局部变量。不跟踪来自其他函数的变量,即使是@live函数,因为与其他函数的交互分析完全依赖于该函数签名,而不是其内部。不跟踪常量参数。

所有者是指向内存对象图的唯一指针。所有者指针通常没有范围属性。如果使用不是从跟踪指针派生的表达式初始化具有作用域属性的指针,则该指针是所有者。

如果将所有者指针分配给另一个所有者指针,则前者进入未定义状态。

借用的指针是临时成为指向内存对象图的唯一指针的指针。它通过从所有者指针赋值进入该状态,然后所有者进入Lent状态,直到最后一次使用借用的指针。

借用的指针必须具有Scope属性,并且必须是指向可变的指针。

只读指针从所有者处获取其值。当只读指针处于活动状态时,只能从该所有者获取只读指针。只读指针必须具有Scope属性,并且不能是指向可变的指针。

借用或只读指针值的生存期从第一次读取时开始(而不是在初始化或赋值时),并在上次读取该值时结束。

为其分配存储(例如堆栈上的局部变量),这会将指针置于未定义状态。

赋值-源指针和目标指针根据它们所处的状态以及它们的类型和存储类更改状态。

传递给OUT函数参数(函数返回后更改状态),与初始化处理相同。

通过ref传递给函数参数,根据参数的存储类和类型将其视为对BORROW或READONY的赋值。

它按值传递给函数参数,该参数被视为对该参数的赋值。

将获取指针的地址,该地址将被视为分配给接收该地址的任何人。

获取内存对象图的任何部分的地址,该地址被视为分配给接收该地址的任何人

从内存对象图的任何部分读取指针值,将其视为对接收该指针的任何人的赋值。

控制流的合并基于每个变量从每条边获得的状态来协调每个变量的状态。

作为一个原型,有很多方面还没有被处理,直到原型显示出它是一个好的设计,才会被处理。

预计会有很多错误。请将它们报告给Bugzilla,并使用关键字";ob";进行标记。没有必要报告这里列举的其他限制。

追踪的是所有者的泄密情况,而不是其他指针。如果借款人不是从指针初始化的,则它们被视为所有者。

@live void uhoh(){scope p=malloc();//p被视为所有者作用域const pc=malloc();//pc不被视为所有者}//退出时未检测到悬挂指针pc。

像作用域这样的指针似乎没有多大意义,也许这可以通过犯这样一个错误来解决。

@live void Ohno(){auto p=malloc();void skaky(){free(P);}skinaky();free(P);//未检测到双重释放}

@live void leaky(){auto p=malloc();Pcher();//抛出异常,p泄漏释放(P);}。

void*xmalloc(Size_T);void xfree(void*);void*ymalloc(Size_T);void yfree(void*);auto p=xmalloc(20);yfree(P);//应该改为调用xfree。

u*umalloc();void ufree(U*);V*vmalloc();void vfree(V*);auto p=umalloc();vfree(P);//类型不匹配。

各种函数(如printf)的参数被视为已使用。虽然安全,但这似乎不是很实用,很可能需要重新考虑。

添加了-PREVIEW=in,以使存储类中的平均作用域为常量。尽管在技术上定义为Const Scope,但In存储类在此预览切换之前从未实现为Const Scope。现在已经完成了实现,In应该是纯输入函数参数的首选存储类。

根据printf的格式说明符验证printf和scanf(也是变体)参数,它采用宽泛而不是严格的兼容性视图。例如,可以使用有符号说明符设置无符号值的格式。

通过为类printf函数添加杂注(Printf)或为类scanf函数添加杂注(Scanf)前缀来检测类似printf和scanf函数。

将FORMAT参数紧跟在.之前。对于非v函数,或紧跟在va_list参数之前(这是";v";printf和scanf的变体的最后一个参数)

现在支持环境变量SOURCE_DATE_EPOCH,环境变量SOURCE_DATE_EPOCH用于可重复构建。它是UNIX时间戳(自1970-01-01 00:00:00以来的秒数),如下所述。DMD现在可以正确识别它,并将相应地设置__DATE__、__TIME__和__TIMESTAMP__内标识。

添加了类似C#/Java isAssignableFrom的TypeInfo_Class/TypeInfo_Interface.isBaseOf。如果参数和接收器相等,或者如果参数表示的类继承了接收器表示的类,则TypeInfo_Class.isBaseOf返回TRUE。这称为isBaseOf,而不是isAssignableFrom,以避免重载opAssign的类混淆,因此可能允许从继承层次结构之外的类进行赋值,并与D运行时中的现有术语相匹配。TypeInfo_Interface.isBaseOf类似于参数可以是TypeInfo_Class或TypeInfo_Interface。

class ClassA{}class ClassB:ClassA{}auto a=new ClassA(),b=new ClassB();Assert(typeid(A).isBaseOf(typeid(A);Assert(typeid(A).isBaseOf(typeid(B);Assert(!typeid(B).isBaseOf(typeid(A));

添加core.ememy.pageSize和minumPageSize。这是一个编译时间、特定于平台的值。此值可能不准确,因为可能会更改此值。只要有可能,请改用pageSize,它是在运行时初始化的。

当上下文需要编译时已知值时,最小大小非常有用,比如静态数组的大小:ubyte[minumPageSize]缓冲区。

现在可以将ISO 8601周日历转换为日期和日期时间使用的公历。

日期由ISO周日历中的年份、周编号和一周中的某一天构成。Date.fromISOWeek(2020,11,DayOfWeek.mon)将得到日期(2020,3,9)。

由于公历中的年份和ISO周日历中的年份并不总是相同的,因此有一个新的.isoWeekYear属性来获取ISO周日历中Date对象的年份。如果您经常在它们之间进行转换,请考虑使用.isoWeekAndYear一步计算周数和年份。

模块std.xml已弃用模块std.xml已弃用。任何仍然需要它的代码都可以改用不死族。对于解析XML文件,我们建议使用复制包dxml。

std.digest.digest中不推荐使用的别名已删除,它们从2.076.1开始就不推荐使用,现在已删除。改为导入std.digest或其子模块。

此外,std.digest.digest的弃用周期已经启动,该模块将在2.101中删除。

隐藏目录现在被忽略。大多数POSIX文件系统上的隐藏目录都以句点开头。例如.dub。默认情况下,dub忽略隐藏文件(例如.swap.file.d),但不忽略隐藏目录。一些操作系统会创建DUB试图包含以进行编译的隐藏目录。此版本现在将正确忽略隐藏目录,除非这些目录在DUB配方文件中特别指定。

D2.092.0:bugzilla 20084中所有错误修复和增强的列表:通过自动引用返回不安全-以及针对输入引用和引用的不同代码。

bugzilla 20711:对象。update需要";update&34;回调来浪费地返回更新值的副本。

bugzilla 20741:dup,idup用于数组加上键,用于内置关联数组的值:如果已知类型具有postblit,则不发出用于非postblit路径的代码,反之亦然